Merge "Software-only implementation of glyph positioning (bug 5443796)"
diff --git a/Android.mk b/Android.mk
index e577b91..5fb66ab 100644
--- a/Android.mk
+++ b/Android.mk
@@ -89,7 +89,13 @@
 	core/java/android/bluetooth/IBluetoothA2dp.aidl \
 	core/java/android/bluetooth/IBluetoothCallback.aidl \
 	core/java/android/bluetooth/IBluetoothHeadset.aidl \
+	core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl \
+	core/java/android/bluetooth/IBluetoothHealth.aidl \
 	core/java/android/bluetooth/IBluetoothHealthCallback.aidl \
+	core/java/android/bluetooth/IBluetoothInputDevice.aidl \
+	core/java/android/bluetooth/IBluetoothPan.aidl \
+	core/java/android/bluetooth/IBluetoothManager.aidl \
+	core/java/android/bluetooth/IBluetoothManagerCallback.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
 	core/java/android/content/IClipboard.aidl \
diff --git a/api/current.txt b/api/current.txt
index 17ab2e5..e5e06d1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -72,6 +72,7 @@
     field public static final java.lang.String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
     field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
     field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
+    field public static final java.lang.String NET_TUNNELING = "android.permission.NET_TUNNELING";
     field public static final java.lang.String NFC = "android.permission.NFC";
     field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
     field public static final java.lang.String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
@@ -4438,6 +4439,7 @@
 package android.bluetooth {
 
   public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
+    method public void finalize();
     method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
     method public int getConnectionState(android.bluetooth.BluetoothDevice);
     method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
@@ -25210,7 +25212,7 @@
     field public static final deprecated int FLAG_BLUR_BEHIND = 4; // 0x4
     field public static final int FLAG_DIM_BEHIND = 2; // 0x2
     field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000
-    field public static final int FLAG_DITHER = 4096; // 0x1000
+    field public static final deprecated int FLAG_DITHER = 4096; // 0x1000
     field public static final int FLAG_FORCE_NOT_FULLSCREEN = 2048; // 0x800
     field public static final int FLAG_FULLSCREEN = 1024; // 0x400
     field public static final int FLAG_HARDWARE_ACCELERATED = 16777216; // 0x1000000
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 71c5622..3314dc3 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -33,6 +33,7 @@
     { AID_MEDIA, "media.audio_policy" },
     { AID_DRM,   "drm.drmManager" },
     { AID_NFC,   "nfc" },
+    { AID_BLUETOOTH, "bluetooth" },
     { AID_RADIO, "radio.phone" },
     { AID_RADIO, "radio.sms" },
     { AID_RADIO, "radio.phonesubinfo" },
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 5e21403..4a75c05 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.policy.PolicyManager;
 
+import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -294,6 +295,11 @@
                     return new MediaRouter(ctx);
                 }});
 
+        registerService(BLUETOOTH_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
+                    return BluetoothAdapter.getDefaultAdapter();
+                }});
+
         registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     return new ClipboardManager(ctx.getOuterContext(),
@@ -361,10 +367,10 @@
                     return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
                 }});
 
-        registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
-                public Object createStaticService() {
+        registerService(LOCATION_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(LOCATION_SERVICE);
-                    return new LocationManager(ILocationManager.Stub.asInterface(b));
+                    return new LocationManager(ctx, ILocationManager.Stub.asInterface(b));
                 }});
 
         registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java
index c2f5ac1..5b5506d 100644
--- a/core/java/android/app/MediaRouteActionProvider.java
+++ b/core/java/android/app/MediaRouteActionProvider.java
@@ -26,6 +26,7 @@
 import android.view.ActionProvider;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
 
 import java.lang.ref.WeakReference;
 
@@ -82,6 +83,8 @@
         mView = new MediaRouteButton(mContext);
         mView.setRouteTypes(mRouteTypes);
         mView.setExtendedSettingsClickListener(mExtendedSettingsListener);
+        mView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
         return mView;
     }
 
diff --git a/core/java/android/bluetooth/AtCommandHandler.java b/core/java/android/bluetooth/AtCommandHandler.java
deleted file mode 100644
index 6deab34..0000000
--- a/core/java/android/bluetooth/AtCommandHandler.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.bluetooth.AtCommandResult;
-
-/**
- * Handler Interface for {@link AtParser}.<p>
- * @hide
- */
-public abstract class AtCommandHandler {
-
-    /**
-     * Handle Basic commands "ATA".<p>
-     * These are single letter commands such as ATA and ATD. Anything following
-     * the single letter command ('A' and 'D' respectively) will be passed as
-     * 'arg'.<p>
-     * For example, "ATDT1234" would result in the call
-     * handleBasicCommand("T1234").<p>
-     * @param arg Everything following the basic command character.
-     * @return    The result of this command.
-     */
-    public AtCommandResult handleBasicCommand(String arg) {
-        return new AtCommandResult(AtCommandResult.ERROR);
-    }
-
-    /**
-     * Handle Actions command "AT+FOO".<p>
-     * Action commands are part of the Extended command syntax, and are
-     * typically used to signal an action on "FOO".<p>
-     * @return The result of this command.
-     */
-    public AtCommandResult handleActionCommand() {
-        return new AtCommandResult(AtCommandResult.ERROR);
-    }
-
-    /**
-     * Handle Read command "AT+FOO?".<p>
-     * Read commands are part of the Extended command syntax, and are
-     * typically used to read the value of "FOO".<p>
-     * @return The result of this command.
-     */
-    public AtCommandResult handleReadCommand() {
-        return new AtCommandResult(AtCommandResult.ERROR);
-    }
-
-    /**
-     * Handle Set command "AT+FOO=...".<p>
-     * Set commands are part of the Extended command syntax, and are
-     * typically used to set the value of "FOO". Multiple arguments can be
-     * sent.<p>
-     * AT+FOO=[<arg1>[,<arg2>[,...]]]<p>
-     * Each argument will be either numeric (Integer) or String.
-     * handleSetCommand is passed a generic Object[] array in which each
-     * element will be an Integer (if it can be parsed with parseInt()) or
-     * String.<p>
-     * Missing arguments ",," are set to empty Strings.<p>
-     * @param args Array of String and/or Integer's. There will always be at
-     *             least one element in this array.
-     * @return     The result of this command.
-     */
-    // Typically used to set this parameter
-    public AtCommandResult handleSetCommand(Object[] args) {
-        return new AtCommandResult(AtCommandResult.ERROR);
-    }
-
-    /**
-     * Handle Test command "AT+FOO=?".<p>
-     * Test commands are part of the Extended command syntax, and are typically
-     * used to request an indication of the range of legal values that "FOO"
-     * can take.<p>
-     * By default we return an OK result, to indicate that this command is at
-     * least recognized.<p>
-     * @return The result of this command.
-     */
-    public AtCommandResult handleTestCommand() {
-        return new AtCommandResult(AtCommandResult.OK);
-    }
-
-}
diff --git a/core/java/android/bluetooth/AtCommandResult.java b/core/java/android/bluetooth/AtCommandResult.java
deleted file mode 100644
index 9675234..0000000
--- a/core/java/android/bluetooth/AtCommandResult.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-/**
- * The result of execution of a single AT command.<p>
- *
- *
- * This class can represent the final response to an AT command line, and also
- * intermediate responses to a single command within a chained AT command
- * line.<p>
- *
- * The actual responses that are intended to be send in reply to the AT command
- * line are stored in a string array. The final response is stored as an
- * int enum, converted to a string when toString() is called. Only a single
- * final response is sent from multiple commands chained into a single command
- * line.<p>
- * @hide
- */
-public class AtCommandResult {
-    // Result code enumerations
-    public static final int OK = 0;
-    public static final int ERROR = 1;
-    public static final int UNSOLICITED = 2;
-
-    private static final String OK_STRING = "OK";
-    private static final String ERROR_STRING = "ERROR";
-
-    private int mResultCode;  // Result code
-    private StringBuilder mResponse; // Response with CRLF line breaks
-
-    /**
-     * Construct a new AtCommandResult with given result code, and an empty
-     * response array.
-     * @param resultCode One of OK, ERROR or UNSOLICITED.
-     */
-    public AtCommandResult(int resultCode) {
-        mResultCode = resultCode;
-        mResponse = new StringBuilder();
-    }
-
-    /**
-     * Construct a new AtCommandResult with result code OK, and the specified
-     * single line response.
-     * @param response The single line response.
-     */
-    public AtCommandResult(String response) {
-        this(OK);
-        addResponse(response);
-    }
-
-    public int getResultCode() {
-        return mResultCode;
-    }
-
-    /**
-     * Add another line to the response.
-     */
-    public void addResponse(String response) {
-        appendWithCrlf(mResponse, response);
-    }
-
-    /**
-     * Add the given result into this AtCommandResult object.<p>
-     * Used to combine results from multiple commands in a single command line
-     * (command chaining).
-     * @param result The AtCommandResult to add to this result.
-     */
-    public void addResult(AtCommandResult result) {
-        if (result != null) {
-            appendWithCrlf(mResponse, result.mResponse.toString());
-            mResultCode = result.mResultCode;
-        }
-    }
-
-    /**
-     * Generate the string response ready to send
-     */
-    public String toString() {
-        StringBuilder result = new StringBuilder(mResponse.toString());
-        switch (mResultCode) {
-        case OK:
-            appendWithCrlf(result, OK_STRING);
-            break;
-        case ERROR:
-            appendWithCrlf(result, ERROR_STRING);
-            break;
-        }
-        return result.toString();
-    }
-
-    /** Append a string to a string builder, joining with a double
-     * CRLF. Used to create multi-line AT command replies
-     */
-    public static void appendWithCrlf(StringBuilder str1, String str2) {
-        if (str1.length() > 0 && str2.length() > 0) {
-            str1.append("\r\n\r\n");
-        }
-        str1.append(str2);
-    }
-};
diff --git a/core/java/android/bluetooth/AtParser.java b/core/java/android/bluetooth/AtParser.java
deleted file mode 100644
index 328fb2b..0000000
--- a/core/java/android/bluetooth/AtParser.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import java.util.*;
-
-/**
- * An AT (Hayes command) Parser based on (a subset of) the ITU-T V.250 standard.
- * <p>
- *
- * Conformant with the subset of V.250 required for implementation of the
- * Bluetooth Headset and Handsfree Profiles, as per Bluetooth SIP
- * specifications. Also implements some V.250 features not required by
- * Bluetooth - such as chained commands.<p>
- *
- * Command handlers are registered with an AtParser object. These handlers are
- * invoked when command lines are processed by AtParser's process() method.<p>
- *
- * The AtParser object accepts a new command line to parse via its process()
- * method. It breaks each command line into one or more commands. Each command
- * is parsed for name, type, and (optional) arguments, and an appropriate
- * external handler method is called through the AtCommandHandler interface.
- *
- * The command types are<ul>
- * <li>Basic Command. For example "ATDT1234567890". Basic command names are a
- * single character (e.g. "D"), and everything following this character is
- * passed to the handler as a string argument (e.g. "T1234567890").
- * <li>Action Command. For example "AT+CIMI". The command name is "CIMI", and
- * there are no arguments for action commands.
- * <li>Read Command. For example "AT+VGM?". The command name is "VGM", and there
- * are no arguments for get commands.
- * <li>Set Command. For example "AT+VGM=14". The command name is "VGM", and
- * there is a single integer argument in this case. In the general case then
- * can be zero or more arguments (comma delimited) each of integer or string
- * form.
- * <li>Test Command. For example "AT+VGM=?. No arguments.
- * </ul>
- *
- * In V.250 the last four command types are known as Extended Commands, and
- * they are used heavily in Bluetooth.<p>
- *
- * Basic commands cannot be chained in this implementation. For Bluetooth
- * headset/handsfree use this is acceptable, because they only use the basic
- * commands ATA and ATD, which are not allowed to be chained. For general V.250
- * use we would need to improve this class to allow Basic command chaining -
- * however it's tricky to get right because there is no delimiter for Basic
- * command chaining.<p>
- *
- * Extended commands can be chained. For example:<p>
- * AT+VGM?;+VGM=14;+CIMI<p>
- * This is equivalent to:<p>
- * AT+VGM?
- * AT+VGM=14
- * AT+CIMI
- * Except that only one final result code is return (although several
- * intermediate responses may be returned), and as soon as one command in the
- * chain fails the rest are abandoned.<p>
- *
- * Handlers are registered by there command name via register(Char c, ...) or
- * register(String s, ...). Handlers for Basic command should be registered by
- * the basic command character, and handlers for Extended commands should be
- * registered by String.<p>
- *
- * Refer to:<ul>
- * <li>ITU-T Recommendation V.250
- * <li>ETSI TS 127.007  (AT Command set for User Equipment, 3GPP TS 27.007)
- * <li>Bluetooth Headset Profile Spec (K6)
- * <li>Bluetooth Handsfree Profile Spec (HFP 1.5)
- * </ul>
- * @hide
- */
-public class AtParser {
-
-    // Extended command type enumeration, only used internally
-    private static final int TYPE_ACTION = 0;   // AT+FOO
-    private static final int TYPE_READ = 1;     // AT+FOO?
-    private static final int TYPE_SET = 2;      // AT+FOO=
-    private static final int TYPE_TEST = 3;     // AT+FOO=?
-
-    private HashMap<String, AtCommandHandler> mExtHandlers;
-    private HashMap<Character, AtCommandHandler> mBasicHandlers;
-
-    private String mLastInput;  // for "A/" (repeat last command) support
-
-    /**
-     * Create a new AtParser.<p>
-     * No handlers are registered.
-     */
-    public AtParser() {
-        mBasicHandlers = new HashMap<Character, AtCommandHandler>();
-        mExtHandlers = new HashMap<String, AtCommandHandler>();
-        mLastInput = "";
-    }
-
-    /**
-     * Register a Basic command handler.<p>
-     * Basic command handlers are later called via their
-     * <code>handleBasicCommand(String args)</code> method.
-     * @param  command Command name - a single character
-     * @param  handler Handler to register
-     */
-    public void register(Character command, AtCommandHandler handler) {
-        mBasicHandlers.put(command, handler);
-    }
-
-    /**
-     * Register an Extended command handler.<p>
-     * Extended command handlers are later called via:<ul>
-     * <li><code>handleActionCommand()</code>
-     * <li><code>handleGetCommand()</code>
-     * <li><code>handleSetCommand()</code>
-     * <li><code>handleTestCommand()</code>
-     * </ul>
-     * Only one method will be called for each command processed.
-     * @param  command Command name - can be multiple characters
-     * @param  handler Handler to register
-     */
-    public void register(String command, AtCommandHandler handler) {
-        mExtHandlers.put(command, handler);
-    }
-
-
-    /**
-     * Strip input of whitespace and force Uppercase - except sections inside
-     * quotes. Also fixes unmatched quotes (by appending a quote). Double
-     * quotes " are the only quotes allowed by V.250
-     */
-    static private String clean(String input) {
-        StringBuilder out = new StringBuilder(input.length());
-
-        for (int i = 0; i < input.length(); i++) {
-            char c = input.charAt(i);
-            if (c == '"') {
-                int j = input.indexOf('"', i + 1 );  // search for closing "
-                if (j == -1) {  // unmatched ", insert one.
-                    out.append(input.substring(i, input.length()));
-                    out.append('"');
-                    break;
-                }
-                out.append(input.substring(i, j + 1));
-                i = j;
-            } else if (c != ' ') {
-                out.append(Character.toUpperCase(c));
-            }
-        }
-
-        return out.toString();
-    }
-
-    static private boolean isAtoZ(char c) {
-        return (c >= 'A' && c <= 'Z');
-    }
-
-    /**
-     * Find a character ch, ignoring quoted sections.
-     * Return input.length() if not found.
-     */
-    static private int findChar(char ch, String input, int fromIndex) {
-        for (int i = fromIndex; i < input.length(); i++) {
-            char c = input.charAt(i);
-            if (c == '"') {
-                i = input.indexOf('"', i + 1);
-                if (i == -1) {
-                    return input.length();
-                }
-            } else if (c == ch) {
-                return i;
-            }
-        }
-        return input.length();
-    }
-
-    /**
-     * Break an argument string into individual arguments (comma delimited).
-     * Integer arguments are turned into Integer objects. Otherwise a String
-     * object is used.
-     */
-    static private Object[] generateArgs(String input) {
-        int i = 0;
-        int j;
-        ArrayList<Object> out = new ArrayList<Object>();
-        while (i <= input.length()) {
-            j = findChar(',', input, i);
-
-            String arg = input.substring(i, j);
-            try {
-                out.add(new Integer(arg));
-            } catch (NumberFormatException e) {
-                out.add(arg);
-            }
-
-            i = j + 1; // move past comma
-        }
-        return out.toArray();
-    }
-
-    /**
-     * Return the index of the end of character after the last character in
-     * the extended command name. Uses the V.250 spec for allowed command
-     * names.
-     */
-    static private int findEndExtendedName(String input, int index) {
-        for (int i = index; i < input.length(); i++) {
-            char c = input.charAt(i);
-
-            // V.250 defines the following chars as legal extended command
-            // names
-            if (isAtoZ(c)) continue;
-            if (c >= '0' && c <= '9') continue;
-            switch (c) {
-            case '!':
-            case '%':
-            case '-':
-            case '.':
-            case '/':
-            case ':':
-            case '_':
-                continue;
-            default:
-                return i;
-            }
-        }
-        return input.length();
-    }
-
-    /**
-     * Processes an incoming AT command line.<p>
-     * This method will invoke zero or one command handler methods for each
-     * command in the command line.<p>
-     * @param raw_input The AT input, without EOL delimiter (e.g. <CR>).
-     * @return          Result object for this command line. This can be
-     *                  converted to a String[] response with toStrings().
-     */
-    public AtCommandResult process(String raw_input) {
-        String input = clean(raw_input);
-
-        // Handle "A/" (repeat previous line)
-        if (input.regionMatches(0, "A/", 0, 2)) {
-            input = new String(mLastInput);
-        } else {
-            mLastInput = new String(input);
-        }
-
-        // Handle empty line - no response necessary
-        if (input.equals("")) {
-            // Return []
-            return new AtCommandResult(AtCommandResult.UNSOLICITED);
-        }
-
-        // Anything else deserves an error
-        if (!input.regionMatches(0, "AT", 0, 2)) {
-            // Return ["ERROR"]
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-
-        // Ok we have a command that starts with AT. Process it
-        int index = 2;
-        AtCommandResult result =
-                new AtCommandResult(AtCommandResult.UNSOLICITED);
-        while (index < input.length()) {
-            char c = input.charAt(index);
-
-            if (isAtoZ(c)) {
-                // Option 1: Basic Command
-                // Pass the rest of the line as is to the handler. Do not
-                // look for any more commands on this line.
-                String args = input.substring(index + 1);
-                if (mBasicHandlers.containsKey((Character)c)) {
-                    result.addResult(mBasicHandlers.get(
-                            (Character)c).handleBasicCommand(args));
-                    return result;
-                } else {
-                    // no handler
-                    result.addResult(
-                            new AtCommandResult(AtCommandResult.ERROR));
-                    return result;
-                }
-                // control never reaches here
-            }
-
-            if (c == '+') {
-                // Option 2: Extended Command
-                // Search for first non-name character. Short-circuit if
-                // we don't handle this command name.
-                int i = findEndExtendedName(input, index + 1);
-                String commandName = input.substring(index, i);
-                if (!mExtHandlers.containsKey(commandName)) {
-                    // no handler
-                    result.addResult(
-                            new AtCommandResult(AtCommandResult.ERROR));
-                    return result;
-                }
-                AtCommandHandler handler = mExtHandlers.get(commandName);
-
-                // Search for end of this command - this is usually the end of
-                // line
-                int endIndex = findChar(';', input, index);
-
-                // Determine what type of command this is.
-                // Default to TYPE_ACTION if we can't find anything else
-                // obvious.
-                int type;
-
-                if (i >= endIndex) {
-                    type = TYPE_ACTION;
-                } else if (input.charAt(i) == '?') {
-                    type = TYPE_READ;
-                } else if (input.charAt(i) == '=') {
-                    if (i + 1 < endIndex) {
-                        if (input.charAt(i + 1) == '?') {
-                            type = TYPE_TEST;
-                        } else {
-                            type = TYPE_SET;
-                        }
-                    } else {
-                        type = TYPE_SET;
-                    }
-                } else {
-                    type = TYPE_ACTION;
-                }
-
-                // Call this command. Short-circuit as soon as a command fails
-                switch (type) {
-                case TYPE_ACTION:
-                    result.addResult(handler.handleActionCommand());
-                    break;
-                case TYPE_READ:
-                    result.addResult(handler.handleReadCommand());
-                    break;
-                case TYPE_TEST:
-                    result.addResult(handler.handleTestCommand());
-                    break;
-                case TYPE_SET:
-                    Object[] args =
-                            generateArgs(input.substring(i + 1, endIndex));
-                    result.addResult(handler.handleSetCommand(args));
-                    break;
-                }
-                if (result.getResultCode() != AtCommandResult.OK) {
-                    return result;   // short-circuit
-                }
-
-                index = endIndex;
-            } else {
-                // Can't tell if this is a basic or extended command.
-                // Push forwards and hope we hit something.
-                index++;
-            }
-        }
-        // Finished processing (and all results were ok)
-        return result;
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
old mode 100644
new mode 100755
index 7300107..74f634b
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -18,12 +18,13 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.server.BluetoothA2dpService;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -43,7 +44,7 @@
  */
 public final class BluetoothA2dp implements BluetoothProfile {
     private static final String TAG = "BluetoothA2dp";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Intent used to broadcast the change in connection state of the A2DP
@@ -102,37 +103,90 @@
      */
     public static final int STATE_NOT_PLAYING   =  11;
 
+    private Context mContext;
     private ServiceListener mServiceListener;
     private IBluetoothA2dp mService;
     private BluetoothAdapter mAdapter;
 
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (DBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (DBG) Log.d(TAG,"Binding service...");
+                                    if (!mContext.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
+                                        Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
+                                    }
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
     /**
      * Create a BluetoothA2dp proxy object for interacting with the local
      * Bluetooth A2DP service.
      *
      */
-    /*package*/ BluetoothA2dp(Context mContext, ServiceListener l) {
-        IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE);
+    /*package*/ BluetoothA2dp(Context context, ServiceListener l) {
+        mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (b != null) {
-            mService = IBluetoothA2dp.Stub.asInterface(b);
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.A2DP, this);
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
             }
-        } else {
-            Log.w(TAG, "Bluetooth A2DP service not available!");
+        }
 
-            // Instead of throwing an exception which prevents people from going
-            // into Wireless settings in the emulator. Let it crash later when it is actually used.
-            mService = null;
+        if (!context.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
         }
     }
 
     /*package*/ void close() {
         mServiceListener = null;
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
     }
 
+    public void finalize() {
+        close();
+    }
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
@@ -267,7 +321,7 @@
      * Set priority of the profile
      *
      * <p> The device should already be paired.
-     *  Priority can be one of {@link #PRIORITY_ON} or
+     *  Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
      * {@link #PRIORITY_OFF},
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
@@ -283,7 +337,8 @@
         if (mService != null && isEnabled()
             && isValidDevice(device)) {
             if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
+                priority != BluetoothProfile.PRIORITY_ON &&
+                priority != BluetoothProfile.PRIORITY_AUTO_CONNECT) {
               return false;
             }
             try {
@@ -347,67 +402,6 @@
     }
 
     /**
-     * Initiate suspend from an A2DP sink.
-     *
-     * <p> This API will return false in scenarios like the A2DP
-     * device is not in connected state etc. When this API returns,
-     * true, it is guaranteed that {@link #ACTION_CONNECTION_STATE_CHANGED}
-     * intent will be broadcasted with the state. Users can get the
-     * state of the A2DP device from this intent.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     * permission.
-     *
-     * @param device Remote A2DP sink
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean suspendSink(BluetoothDevice device) {
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
-            try {
-                return mService.suspendSink(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
-     * Initiate resume from a suspended A2DP sink.
-     *
-     * <p> This API will return false in scenarios like the A2DP
-     * device is not in suspended state etc. When this API returns,
-     * true, it is guaranteed that {@link #ACTION_SINK_STATE_CHANGED}
-     * intent will be broadcasted with the state. Users can get the
-     * state of the A2DP device from this intent.
-     *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
-     *
-     * @param device Remote A2DP sink
-     * @return false on immediate error,
-     *               true otherwise
-     * @hide
-     */
-    public boolean resumeSink(BluetoothDevice device) {
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
-            try {
-                return mService.resumeSink(device);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-                return false;
-            }
-        }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
-        return false;
-    }
-
-    /**
      * This function checks if the remote device is an AVCRP
      * target and thus whether we should send volume keys
      * changes or not.
@@ -428,23 +422,6 @@
     }
 
     /**
-     * Allow or disallow incoming connection
-     * @param device Sink
-     * @param value True / False
-     * @return Success or Failure of the binder call.
-     * @hide
-     */
-    public boolean allowIncomingConnect(BluetoothDevice device, boolean value) {
-        if (DBG) log("allowIncomingConnect(" + device + ":" + value + ")");
-        try {
-            return mService.allowIncomingConnect(device, value);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            return false;
-        }
-    }
-
-    /**
      * Helper for converting a state to a string.
      *
      * For debug use only - strings are not internationalized.
@@ -469,6 +446,24 @@
         }
     }
 
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothA2dp.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP);
+            }
+        }
+    };
+
     private boolean isEnabled() {
        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
        return false;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
old mode 100644
new mode 100755
index 8e3df47..dc18029
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -31,6 +31,7 @@
 import android.util.Pair;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -73,7 +74,7 @@
  */
 public final class BluetoothAdapter {
     private static final String TAG = "BluetoothAdapter";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Sentinel error value for this class. Guaranteed to not equal any other
@@ -343,7 +344,7 @@
     public static final int STATE_DISCONNECTING = 3;
 
     /** @hide */
-    public static final String BLUETOOTH_SERVICE = "bluetooth";
+    public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
 
     private static final int ADDRESS_LENGTH = 17;
 
@@ -353,7 +354,8 @@
      */
     private static BluetoothAdapter sAdapter;
 
-    private final IBluetooth mService;
+    private final IBluetoothManager mManagerService;
+    private IBluetooth mService;
 
     private Handler mServiceRecordHandler;
 
@@ -367,10 +369,12 @@
      */
     public static synchronized BluetoothAdapter getDefaultAdapter() {
         if (sAdapter == null) {
-            IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
             if (b != null) {
-                IBluetooth service = IBluetooth.Stub.asInterface(b);
-                sAdapter = new BluetoothAdapter(service);
+                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
+                sAdapter = new BluetoothAdapter(managerService);
+            } else {
+                Log.e(TAG, "Bluetooth binder is null");
             }
         }
         return sAdapter;
@@ -378,13 +382,16 @@
 
     /**
      * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
-     * @hide
      */
-    public BluetoothAdapter(IBluetooth service) {
-        if (service == null) {
-            throw new IllegalArgumentException("service is null");
+    BluetoothAdapter(IBluetoothManager managerService) {
+
+        if (managerService == null) {
+            throw new IllegalArgumentException("bluetooth manager service is null");
         }
-        mService = service;
+        try {
+            mService = managerService.registerAdapter(mManagerCallback);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        mManagerService = managerService;
         mServiceRecordHandler = null;
     }
 
@@ -432,8 +439,11 @@
      * @return true if the local adapter is turned on
      */
     public boolean isEnabled() {
+
         try {
-            return mService.isEnabled();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.isEnabled();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -451,8 +461,18 @@
      */
     public int getState() {
         try {
-            return mService.getBluetoothState();
+            synchronized(mManagerCallback) {
+                if (mService != null)
+                {
+                    int state=  mService.getState();
+                    if (DBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state);
+                    return state;
+                }
+                // TODO(BT) there might be a small gap during STATE_TURNING_ON that
+                //          mService is null, handle that case
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
+        if (DBG) Log.d(TAG, "" + hashCode() + ": getState() :  mService = null. Returning STATE_OFF");
         return STATE_OFF;
     }
 
@@ -484,8 +504,9 @@
      *         immediate error
      */
     public boolean enable() {
+        boolean enabled = false;
         try {
-            return mService.enable();
+            return mManagerService.enable();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -516,7 +537,25 @@
      */
     public boolean disable() {
         try {
-            return mService.disable(true);
+            return mManagerService.disable(true);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
+    /**
+     * Turn off the local Bluetooth adapter and don't persist the setting.
+     *
+     * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission
+     *
+     * @return true to indicate adapter shutdown has begun, or false on
+     *         immediate error
+     * @hide
+     */
+    public boolean disable(boolean persist) {
+
+        try {
+            return mManagerService.disable(persist);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -530,7 +569,7 @@
      */
     public String getAddress() {
         try {
-            return mService.getAddress();
+            return mManagerService.getAddress();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -544,7 +583,7 @@
      */
     public String getName() {
         try {
-            return mService.getName();
+            return mManagerService.getName();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -560,7 +599,9 @@
     public ParcelUuid[] getUuids() {
         if (getState() != STATE_ON) return null;
         try {
-            return mService.getUuids();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.getUuids();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -583,7 +624,9 @@
     public boolean setName(String name) {
         if (getState() != STATE_ON) return false;
         try {
-            return mService.setName(name);
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.setName(name);
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -607,7 +650,9 @@
     public int getScanMode() {
         if (getState() != STATE_ON) return SCAN_MODE_NONE;
         try {
-            return mService.getScanMode();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.getScanMode();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return SCAN_MODE_NONE;
     }
@@ -643,7 +688,9 @@
     public boolean setScanMode(int mode, int duration) {
         if (getState() != STATE_ON) return false;
         try {
-            return mService.setScanMode(mode, duration);
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.setScanMode(mode, duration);
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -651,14 +698,17 @@
     /** @hide */
     public boolean setScanMode(int mode) {
         if (getState() != STATE_ON) return false;
-        return setScanMode(mode, 120);
+        /* getDiscoverableTimeout() to use the latest from NV than use 0 */
+        return setScanMode(mode, getDiscoverableTimeout());
     }
 
     /** @hide */
     public int getDiscoverableTimeout() {
         if (getState() != STATE_ON) return -1;
         try {
-            return mService.getDiscoverableTimeout();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.getDiscoverableTimeout();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return -1;
     }
@@ -667,7 +717,9 @@
     public void setDiscoverableTimeout(int timeout) {
         if (getState() != STATE_ON) return;
         try {
-            mService.setDiscoverableTimeout(timeout);
+            synchronized(mManagerCallback) {
+                if (mService != null) mService.setDiscoverableTimeout(timeout);
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
     }
 
@@ -704,7 +756,9 @@
     public boolean startDiscovery() {
         if (getState() != STATE_ON) return false;
         try {
-            return mService.startDiscovery();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.startDiscovery();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -729,7 +783,9 @@
     public boolean cancelDiscovery() {
         if (getState() != STATE_ON) return false;
         try {
-            return mService.cancelDiscovery();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.cancelDiscovery();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -756,7 +812,9 @@
     public boolean isDiscovering() {
         if (getState() != STATE_ON) return false;
         try {
-            return mService.isDiscovering();
+            synchronized(mManagerCallback) {
+                if (mService != null ) return mService.isDiscovering();
+            }
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -774,10 +832,13 @@
      */
     public Set<BluetoothDevice> getBondedDevices() {
         if (getState() != STATE_ON) {
-            return toDeviceSet(new String[0]);
+            return toDeviceSet(new BluetoothDevice[0]);
         }
         try {
-            return toDeviceSet(mService.listBonds());
+            synchronized(mManagerCallback) {
+                if (mService != null) return toDeviceSet(mService.getBondedDevices());
+            }
+            return toDeviceSet(new BluetoothDevice[0]);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -798,7 +859,9 @@
     public int getConnectionState() {
         if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED;
         try {
-            return mService.getAdapterConnectionState();
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.getAdapterConnectionState();
+            }
         } catch (RemoteException e) {Log.e(TAG, "getConnectionState:", e);}
         return BluetoothAdapter.STATE_DISCONNECTED;
     }
@@ -821,7 +884,9 @@
     public int getProfileConnectionState(int profile) {
         if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED;
         try {
-            return mService.getProfileConnectionState(profile);
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.getProfileConnectionState(profile);
+            }
         } catch (RemoteException e) {
             Log.e(TAG, "getProfileConnectionState:", e);
         }
@@ -829,51 +894,6 @@
     }
 
     /**
-    /**
-     * Picks RFCOMM channels until none are left.
-     * Avoids reserved channels.
-     */
-    private static class RfcommChannelPicker {
-        private static final int[] RESERVED_RFCOMM_CHANNELS =  new int[] {
-            10,  // HFAG
-            11,  // HSAG
-            12,  // OPUSH
-            19,  // PBAP
-        };
-        private static LinkedList<Integer> sChannels;  // master list of non-reserved channels
-        private static Random sRandom;
-
-        private final LinkedList<Integer> mChannels;  // local list of channels left to try
-
-        private final UUID mUuid;
-
-        public RfcommChannelPicker(UUID uuid) {
-            synchronized (RfcommChannelPicker.class) {
-                if (sChannels == null) {
-                    // lazy initialization of non-reserved rfcomm channels
-                    sChannels = new LinkedList<Integer>();
-                    for (int i = 1; i <= BluetoothSocket.MAX_RFCOMM_CHANNEL; i++) {
-                        sChannels.addLast(new Integer(i));
-                    }
-                    for (int reserved : RESERVED_RFCOMM_CHANNELS) {
-                        sChannels.remove(new Integer(reserved));
-                    }
-                    sRandom = new Random();
-                }
-                mChannels = (LinkedList<Integer>)sChannels.clone();
-            }
-            mUuid = uuid;
-        }
-        /* Returns next random channel, or -1 if we're out */
-        public int nextChannel() {
-            if (mChannels.size() == 0) {
-                return -1;
-            }
-            return mChannels.remove(sRandom.nextInt(mChannels.size()));
-        }
-    }
-
-    /**
      * Create a listening, secure RFCOMM Bluetooth socket.
      * <p>A remote device connecting to this socket will be authenticated and
      * communication on this socket will be encrypted.
@@ -892,10 +912,10 @@
                 BluetoothSocket.TYPE_RFCOMM, true, true, channel);
         int errno = socket.mSocket.bindListen();
         if (errno != 0) {
-            try {
-                socket.close();
-            } catch (IOException e) {}
-            socket.mSocket.throwErrnoNative(errno);
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
+            throw new IOException("Error: " + errno);
         }
         return socket;
     }
@@ -996,70 +1016,23 @@
         return createNewRfcommSocketAndRecord(name, uuid, false, true);
     }
 
+
     private BluetoothServerSocket createNewRfcommSocketAndRecord(String name, UUID uuid,
             boolean auth, boolean encrypt) throws IOException {
-        RfcommChannelPicker picker = new RfcommChannelPicker(uuid);
-
         BluetoothServerSocket socket;
-        int channel;
-        int errno;
-        while (true) {
-            channel = picker.nextChannel();
-
-            if (channel == -1) {
-                throw new IOException("No available channels");
-            }
-
-            socket = new BluetoothServerSocket(
-                    BluetoothSocket.TYPE_RFCOMM, auth, encrypt, channel);
-            errno = socket.mSocket.bindListen();
-            if (errno == 0) {
-                if (DBG) Log.d(TAG, "listening on RFCOMM channel " + channel);
-                break;  // success
-            } else if (errno == BluetoothSocket.EADDRINUSE) {
-                if (DBG) Log.d(TAG, "RFCOMM channel " + channel + " in use");
-                try {
-                    socket.close();
-                } catch (IOException e) {}
-                continue;  // try another channel
-            } else {
-                try {
-                    socket.close();
-                } catch (IOException e) {}
-                socket.mSocket.throwErrnoNative(errno);  // Exception as a result of bindListen()
-            }
+        socket = new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, auth,
+                        encrypt, new ParcelUuid(uuid));
+        socket.setServiceName(name);
+        int errno = socket.mSocket.bindListen();
+        if (errno != 0) {
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
+            throw new IOException("Error: " + errno);
         }
-
-        int handle = -1;
-        try {
-            handle = mService.addRfcommServiceRecord(name, new ParcelUuid(uuid), channel,
-                    new Binder());
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
-        if (handle == -1) {
-            try {
-                socket.close();
-            } catch (IOException e) {}
-            throw new IOException("Not able to register SDP record for " + name);
-        }
-
-        if (mServiceRecordHandler == null) {
-            mServiceRecordHandler = new Handler(Looper.getMainLooper()) {
-                    public void handleMessage(Message msg) {
-                        /* handle socket closing */
-                        int handle = msg.what;
-                        try {
-                            if (DBG) Log.d(TAG, "Removing service record " +
-                                           Integer.toHexString(handle));
-                            mService.removeServiceRecord(handle);
-                        } catch (RemoteException e) {Log.e(TAG, "", e);}
-                    }
-                };
-        }
-        socket.setCloseHandler(mServiceRecordHandler, handle);
         return socket;
     }
 
-
     /**
      * Construct an unencrypted, unauthenticated, RFCOMM server socket.
      * Call #accept to retrieve connections to this socket.
@@ -1073,10 +1046,10 @@
                 BluetoothSocket.TYPE_RFCOMM, false, false, port);
         int errno = socket.mSocket.bindListen();
         if (errno != 0) {
-            try {
-                socket.close();
-            } catch (IOException e) {}
-            socket.mSocket.throwErrnoNative(errno);
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
+            throw new IOException("Error: " + errno);
         }
         return socket;
     }
@@ -1094,11 +1067,11 @@
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_RFCOMM, false, true, port);
         int errno = socket.mSocket.bindListen();
-        if (errno != 0) {
-            try {
-                socket.close();
-            } catch (IOException e) {}
-            socket.mSocket.throwErrnoNative(errno);
+        if (errno < 0) {
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
+            throw new IOException("Error: " + errno);
         }
         return socket;
     }
@@ -1115,11 +1088,10 @@
         BluetoothServerSocket socket = new BluetoothServerSocket(
                 BluetoothSocket.TYPE_SCO, false, false, -1);
         int errno = socket.mSocket.bindListen();
-        if (errno != 0) {
-            try {
-                socket.close();
-            } catch (IOException e) {}
-            socket.mSocket.throwErrnoNative(errno);
+        if (errno < 0) {
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
         }
         return socket;
     }
@@ -1134,6 +1106,8 @@
      */
     public Pair<byte[], byte[]> readOutOfBandData() {
         if (getState() != STATE_ON) return null;
+        //TODO(BT
+        /*
         try {
             byte[] hash;
             byte[] randomizer;
@@ -1151,7 +1125,7 @@
             }
             return new Pair<byte[], byte[]>(hash, randomizer);
 
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
         return null;
     }
 
@@ -1231,6 +1205,41 @@
         }
     }
 
+    final private IBluetoothManagerCallback mManagerCallback =
+        new IBluetoothManagerCallback.Stub() {
+            public void onBluetoothServiceUp(IBluetooth bluetoothService) {
+                if (DBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
+                synchronized (mManagerCallback) {
+                    mService = bluetoothService;
+                    for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
+                        try {
+                            if (cb != null) {
+                                cb.onBluetoothServiceUp(bluetoothService);
+                            } else {
+                                Log.d(TAG, "onBluetoothServiceUp: cb is null!!!");
+                            }
+                        } catch (Exception e)  { Log.e(TAG,"",e);}
+                    }
+                }
+            }
+
+            public void onBluetoothServiceDown() {
+                if (DBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
+                synchronized (mManagerCallback) {
+                    mService = null;
+                    for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
+                        try {
+                            if (cb != null) {
+                                cb.onBluetoothServiceDown();
+                            } else {
+                                Log.d(TAG, "onBluetoothServiceDown: cb is null!!!");
+                            }
+                        } catch (Exception e)  { Log.e(TAG,"",e);}
+                    }
+                }
+            }
+    };
+
     /**
      * Enable the Bluetooth Adapter, but don't auto-connect devices
      * and don't persist state. Only for use by system applications.
@@ -1276,12 +1285,14 @@
                                                    BluetoothStateChangeCallback callback) {
         if (callback == null) return false;
 
+        //TODO(BT)
+        /*
         try {
             return mService.changeApplicationBluetoothState(on, new
                     StateChangeCallbackWrapper(callback), new Binder());
         } catch (RemoteException e) {
             Log.e(TAG, "changeBluetoothState", e);
-        }
+        }*/
         return false;
     }
 
@@ -1309,14 +1320,22 @@
         }
     }
 
-    private Set<BluetoothDevice> toDeviceSet(String[] addresses) {
-        Set<BluetoothDevice> devices = new HashSet<BluetoothDevice>(addresses.length);
-        for (int i = 0; i < addresses.length; i++) {
-            devices.add(getRemoteDevice(addresses[i]));
-        }
-        return Collections.unmodifiableSet(devices);
+    private Set<BluetoothDevice> toDeviceSet(BluetoothDevice[] devices) {
+        Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(Arrays.asList(devices));
+        return Collections.unmodifiableSet(deviceSet);
     }
 
+    protected void finalize() throws Throwable {
+        try {
+            mManagerService.unregisterAdapter(mManagerCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        } finally {
+            super.finalize();
+        }
+    }
+
+
     /**
      * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
      * <p>Alphabetic characters must be uppercase to be valid.
@@ -1347,4 +1366,27 @@
         }
         return true;
     }
+
+    /*package*/ IBluetoothManager getBluetoothManager() {
+            return mManagerService;
+    }
+
+    private ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>();
+
+    /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
+        synchronized (mManagerCallback) {
+            if (cb == null) {
+                Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback");
+            } else if (!mProxyServiceStateCallbacks.contains(cb)) {
+                mProxyServiceStateCallbacks.add(cb);
+            }
+        }
+        return mService;
+    }
+
+    /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
+        synchronized (mManagerCallback) {
+            mProxyServiceStateCallbacks.remove(cb);
+        }
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothAudioGateway.java b/core/java/android/bluetooth/BluetoothAudioGateway.java
deleted file mode 100644
index 9351393..0000000
--- a/core/java/android/bluetooth/BluetoothAudioGateway.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import java.lang.Thread;
-
-import android.os.Message;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * Listens for incoming RFCOMM connection for the headset / handsfree service.
- *
- * TODO: Use the new generic BluetoothSocket class instead of this legacy code
- *
- * @hide
- */
-public final class BluetoothAudioGateway {
-    private static final String TAG = "BT Audio Gateway";
-    private static final boolean DBG = false;
-
-    private int mNativeData;
-    static { classInitNative(); }
-
-    /* in */
-    private int mHandsfreeAgRfcommChannel = -1;
-    private int mHeadsetAgRfcommChannel   = -1;
-
-    /* out - written by native code */
-    private String mConnectingHeadsetAddress;
-    private int mConnectingHeadsetRfcommChannel; /* -1 when not connected */
-    private int mConnectingHeadsetSocketFd;
-    private String mConnectingHandsfreeAddress;
-    private int mConnectingHandsfreeRfcommChannel; /* -1 when not connected */
-    private int mConnectingHandsfreeSocketFd;
-    private int mTimeoutRemainingMs; /* in/out */
-
-    private final BluetoothAdapter mAdapter;
-
-    public static final int DEFAULT_HF_AG_CHANNEL = 10;
-    public static final int DEFAULT_HS_AG_CHANNEL = 11;
-
-    public BluetoothAudioGateway(BluetoothAdapter adapter) {
-        this(adapter, DEFAULT_HF_AG_CHANNEL, DEFAULT_HS_AG_CHANNEL);
-    }
-
-    public BluetoothAudioGateway(BluetoothAdapter adapter, int handsfreeAgRfcommChannel,
-                int headsetAgRfcommChannel) {
-        mAdapter = adapter;
-        mHandsfreeAgRfcommChannel = handsfreeAgRfcommChannel;
-        mHeadsetAgRfcommChannel = headsetAgRfcommChannel;
-        initializeNativeDataNative();
-    }
-
-    private Thread mConnectThead;
-    private volatile boolean mInterrupted;
-    private static final int SELECT_WAIT_TIMEOUT = 1000;
-
-    private Handler mCallback;
-
-    public class IncomingConnectionInfo {
-        public BluetoothAdapter mAdapter;
-        public BluetoothDevice mRemoteDevice;
-        public int mSocketFd;
-        public int mRfcommChan;
-        IncomingConnectionInfo(BluetoothAdapter adapter, BluetoothDevice remoteDevice,
-                int socketFd, int rfcommChan) {
-            mAdapter = adapter;
-            mRemoteDevice = remoteDevice;
-            mSocketFd = socketFd;
-            mRfcommChan = rfcommChan;
-        }
-    }
-
-    public static final int MSG_INCOMING_HEADSET_CONNECTION   = 100;
-    public static final int MSG_INCOMING_HANDSFREE_CONNECTION = 101;
-
-    public synchronized boolean start(Handler callback) {
-
-        if (mConnectThead == null) {
-            mCallback = callback;
-            mConnectThead = new Thread(TAG) {
-                    public void run() {
-                        if (DBG) log("Connect Thread starting");
-                        while (!mInterrupted) {
-                            //Log.i(TAG, "waiting for connect");
-                            mConnectingHeadsetRfcommChannel = -1;
-                            mConnectingHandsfreeRfcommChannel = -1;
-                            if (waitForHandsfreeConnectNative(SELECT_WAIT_TIMEOUT) == false) {
-                                if (mTimeoutRemainingMs > 0) {
-                                    try {
-                                        Log.i(TAG, "select thread timed out, but " + 
-                                              mTimeoutRemainingMs + "ms of waiting remain.");
-                                        Thread.sleep(mTimeoutRemainingMs);
-                                    } catch (InterruptedException e) {
-                                        Log.i(TAG, "select thread was interrupted (2), exiting");
-                                        mInterrupted = true;
-                                    }
-                                }
-                            }
-                            else {
-                                Log.i(TAG, "connect notification!");
-                                /* A device connected (most likely just one, but 
-                                   it is possible for two separate devices, one 
-                                   a headset and one a handsfree, to connect
-                                   simultaneously. 
-                                */
-                                if (mConnectingHeadsetRfcommChannel >= 0) {
-                                    Log.i(TAG, "Incoming connection from headset " + 
-                                          mConnectingHeadsetAddress + " on channel " + 
-                                          mConnectingHeadsetRfcommChannel);
-                                    Message msg = Message.obtain(mCallback);
-                                    msg.what = MSG_INCOMING_HEADSET_CONNECTION;
-                                    msg.obj = new IncomingConnectionInfo(
-                                        mAdapter,
-                                        mAdapter.getRemoteDevice(mConnectingHeadsetAddress),
-                                        mConnectingHeadsetSocketFd,
-                                        mConnectingHeadsetRfcommChannel);
-                                    msg.sendToTarget();
-                                }
-                                if (mConnectingHandsfreeRfcommChannel >= 0) {
-                                    Log.i(TAG, "Incoming connection from handsfree " + 
-                                          mConnectingHandsfreeAddress + " on channel " + 
-                                          mConnectingHandsfreeRfcommChannel);
-                                    Message msg = Message.obtain();
-                                    msg.setTarget(mCallback);
-                                    msg.what = MSG_INCOMING_HANDSFREE_CONNECTION;
-                                    msg.obj = new IncomingConnectionInfo(
-                                        mAdapter,
-                                        mAdapter.getRemoteDevice(mConnectingHandsfreeAddress),
-                                        mConnectingHandsfreeSocketFd,
-                                        mConnectingHandsfreeRfcommChannel);
-                                    msg.sendToTarget();
-                                }
-                            }
-                        }
-                        if (DBG) log("Connect Thread finished");
-                    }
-                };
-
-            if (setUpListeningSocketsNative() == false) {
-                Log.e(TAG, "Could not set up listening socket, exiting");
-                return false;
-            }
-
-            mInterrupted = false;
-            mConnectThead.start();
-        }
-
-        return true;
-    }
-
-    public synchronized void stop() {
-        if (mConnectThead != null) {
-            if (DBG) log("stopping Connect Thread");
-            mInterrupted = true;
-            try {
-                mConnectThead.interrupt();
-                if (DBG) log("waiting for thread to terminate");
-                mConnectThead.join();
-                mConnectThead = null;
-                mCallback = null;
-                tearDownListeningSocketsNative();
-            } catch (InterruptedException e) {
-                Log.w(TAG, "Interrupted waiting for Connect Thread to join");
-            }
-        }
-    }
-
-    protected void finalize() throws Throwable {
-        try {
-            cleanupNativeDataNative();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    private static native void classInitNative();
-    private native void initializeNativeDataNative();
-    private native void cleanupNativeDataNative();
-    private native boolean waitForHandsfreeConnectNative(int timeoutMs);
-    private native boolean setUpListeningSocketsNative();
-    private native void tearDownListeningSocketsNative();
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
old mode 100644
new mode 100755
index 56e1735..2504763
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -65,6 +65,7 @@
  */
 public final class BluetoothDevice implements Parcelable {
     private static final String TAG = "BluetoothDevice";
+    private static final boolean DBG = false;
 
     /**
      * Sentinel error value for this class. Guaranteed to not equal any other
@@ -483,16 +484,29 @@
     /*package*/ static IBluetooth getService() {
         synchronized (BluetoothDevice.class) {
             if (sService == null) {
-                IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
-                if (b == null) {
-                    throw new RuntimeException("Bluetooth service not available");
-                }
-                sService = IBluetooth.Stub.asInterface(b);
+                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+                sService = adapter.getBluetoothService(mStateChangeCallback);
             }
         }
         return sService;
     }
 
+    static IBluetoothManagerCallback mStateChangeCallback = new IBluetoothManagerCallback.Stub() {
+
+        public void onBluetoothServiceUp(IBluetooth bluetoothService)
+                throws RemoteException {
+            synchronized (BluetoothDevice.class) {
+                sService = bluetoothService;
+            }
+        }
+
+        public void onBluetoothServiceDown()
+            throws RemoteException {
+            synchronized (BluetoothDevice.class) {
+                sService = null;
+            }
+        }
+    };
     /**
      * Create a new BluetoothDevice
      * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
@@ -561,6 +575,7 @@
      * @return Bluetooth hardware address as string
      */
     public String getAddress() {
+        if (DBG) Log.d(TAG, "mAddress: " + mAddress);
         return mAddress;
     }
 
@@ -575,8 +590,12 @@
      * @return the Bluetooth name, or null if there was a problem.
      */
     public String getName() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
+            return null;
+        }
         try {
-            return sService.getRemoteName(mAddress);
+            return sService.getRemoteName(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -589,8 +608,12 @@
      * @hide
      */
     public String getAlias() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
+            return null;
+        }
         try {
-            return sService.getRemoteAlias(mAddress);
+            return sService.getRemoteAlias(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -606,8 +629,12 @@
      * @hide
      */
     public boolean setAlias(String alias) {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
+            return false;
+        }
         try {
-            return sService.setRemoteAlias(mAddress, alias);
+            return sService.setRemoteAlias(this, alias);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -642,8 +669,12 @@
      * @hide
      */
     public boolean createBond() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
+            return false;
+        }
         try {
-            return sService.createBond(mAddress);
+            return sService.createBond(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -668,9 +699,11 @@
      * @hide
      */
     public boolean createBondOutOfBand(byte[] hash, byte[] randomizer) {
+        //TODO(BT)
+        /*
         try {
-            return sService.createBondOutOfBand(mAddress, hash, randomizer);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return sService.createBondOutOfBand(this, hash, randomizer);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
         return false;
     }
 
@@ -688,9 +721,11 @@
      * @hide
      */
     public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
+      //TODO(BT)
+      /*
       try {
-        return sService.setDeviceOutOfBandData(mAddress, hash, randomizer);
-      } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return sService.setDeviceOutOfBandData(this, hash, randomizer);
+      } catch (RemoteException e) {Log.e(TAG, "", e);} */
       return false;
     }
 
@@ -702,8 +737,12 @@
      * @hide
      */
     public boolean cancelBondProcess() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
+            return false;
+        }
         try {
-            return sService.cancelBondProcess(mAddress);
+            return sService.cancelBondProcess(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -719,8 +758,12 @@
      * @hide
      */
     public boolean removeBond() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
+            return false;
+        }
         try {
-            return sService.removeBond(mAddress);
+            return sService.removeBond(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -736,8 +779,12 @@
      * @return the bond state
      */
     public int getBondState() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get bond state");
+            return BOND_NONE;
+        }
         try {
-            return sService.getBondState(mAddress);
+            return sService.getBondState(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return BOND_NONE;
     }
@@ -749,8 +796,12 @@
      * @return Bluetooth class object, or null on error
      */
     public BluetoothClass getBluetoothClass() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
+            return null;
+        }
         try {
-            int classInt = sService.getRemoteClass(mAddress);
+            int classInt = sService.getRemoteClass(this);
             if (classInt == BluetoothClass.ERROR) return null;
             return new BluetoothClass(classInt);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
@@ -763,11 +814,13 @@
      * @hide
      */
     public boolean getTrustState() {
+        //TODO(BT)
+        /*
         try {
-            return sService.getTrustState(mAddress);
+            return sService.getTrustState(this);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
-        }
+        }*/
         return false;
     }
 
@@ -778,11 +831,13 @@
      * @hide
      */
     public boolean setTrust(boolean value) {
+        //TODO(BT)
+        /*
         try {
-            return sService.setTrust(mAddress, value);
+            return sService.setTrust(this, value);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
-        }
+        }*/
         return false;
     }
 
@@ -799,8 +854,12 @@
      *         or null on error
      */
      public ParcelUuid[] getUuids() {
+         if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
+             return null;
+         }
         try {
-            return sService.getRemoteUuids(mAddress);
+            return sService.getRemoteUuids(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return null;
     }
@@ -822,64 +881,84 @@
       */
      public boolean fetchUuidsWithSdp() {
         try {
-            return sService.fetchRemoteUuids(mAddress, null, null);
+            return sService.fetchRemoteUuids(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return false;
+            return false;
     }
 
     /** @hide */
     public int getServiceChannel(ParcelUuid uuid) {
+        //TODO(BT)
+        /*
          try {
-             return sService.getRemoteServiceChannel(mAddress, uuid);
-         } catch (RemoteException e) {Log.e(TAG, "", e);}
+             return sService.getRemoteServiceChannel(this, uuid);
+         } catch (RemoteException e) {Log.e(TAG, "", e);}*/
          return BluetoothDevice.ERROR;
     }
 
     /** @hide */
     public boolean setPin(byte[] pin) {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
+            return false;
+        }
         try {
-            return sService.setPin(mAddress, pin);
+            return sService.setPin(this, true, pin.length, pin);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
 
     /** @hide */
     public boolean setPasskey(int passkey) {
+        //TODO(BT)
+        /*
         try {
-            return sService.setPasskey(mAddress, passkey);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return sService.setPasskey(this, true, 4, passkey);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
         return false;
     }
 
     /** @hide */
     public boolean setPairingConfirmation(boolean confirm) {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
+            return false;
+        }
         try {
-            return sService.setPairingConfirmation(mAddress, confirm);
+            return sService.setPairingConfirmation(this, confirm);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
 
     /** @hide */
     public boolean setRemoteOutOfBandData() {
+        // TODO(BT)
+        /*
         try {
-          return sService.setRemoteOutOfBandData(mAddress);
-      } catch (RemoteException e) {Log.e(TAG, "", e);}
+          return sService.setRemoteOutOfBandData(this);
+      } catch (RemoteException e) {Log.e(TAG, "", e);}*/
       return false;
     }
 
     /** @hide */
     public boolean cancelPairingUserInput() {
+        if (sService == null) {
+            Log.e(TAG, "BT not enabled. Cannot create pairing user input");
+            return false;
+        }
         try {
-            return sService.cancelPairingUserInput(mAddress);
+            return sService.cancelBondProcess(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
 
     /** @hide */
     public boolean isBluetoothDock() {
+        // TODO(BT)
+        /*
         try {
-            return sService.isBluetoothDock(mAddress);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            return sService.isBluetoothDock(this);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
         return false;
     }
 
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
deleted file mode 100644
index 020f051..0000000
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Message;
-import android.bluetooth.BluetoothAdapter;
-import android.os.PowerManager;
-import android.server.BluetoothA2dpService;
-import android.server.BluetoothService;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.util.Set;
-
-/**
- * This class is the Profile connection state machine associated with a remote
- * device. When the device bonds an instance of this class is created.
- * This tracks incoming and outgoing connections of all the profiles. Incoming
- * connections are preferred over outgoing connections and HFP preferred over
- * A2DP. When the device is unbonded, the instance is removed.
- *
- * States:
- * {@link BondedDevice}: This state represents a bonded device. When in this
- * state none of the profiles are in transition states.
- *
- * {@link OutgoingHandsfree}: Handsfree profile connection is in a transition
- * state because of a outgoing Connect or Disconnect.
- *
- * {@link IncomingHandsfree}: Handsfree profile connection is in a transition
- * state because of a incoming Connect or Disconnect.
- *
- * {@link IncomingA2dp}: A2dp profile connection is in a transition
- * state because of a incoming Connect or Disconnect.
- *
- * {@link OutgoingA2dp}: A2dp profile connection is in a transition
- * state because of a outgoing Connect or Disconnect.
- *
- * Todo(): Write tests for this class, when the Android Mock support is completed.
- * @hide
- */
-public final class BluetoothDeviceProfileState extends StateMachine {
-    private static final String TAG = "BluetoothDeviceProfileState";
-    private static final boolean DBG = false;
-
-    // TODO(): Restructure the state machine to make it scalable with regard to profiles.
-    public static final int CONNECT_HFP_OUTGOING = 1;
-    public static final int CONNECT_HFP_INCOMING = 2;
-    public static final int CONNECT_A2DP_OUTGOING = 3;
-    public static final int CONNECT_A2DP_INCOMING = 4;
-    public static final int CONNECT_HID_OUTGOING = 5;
-    public static final int CONNECT_HID_INCOMING = 6;
-
-    public static final int DISCONNECT_HFP_OUTGOING = 50;
-    private static final int DISCONNECT_HFP_INCOMING = 51;
-    public static final int DISCONNECT_A2DP_OUTGOING = 52;
-    public static final int DISCONNECT_A2DP_INCOMING = 53;
-    public static final int DISCONNECT_HID_OUTGOING = 54;
-    public static final int DISCONNECT_HID_INCOMING = 55;
-    public static final int DISCONNECT_PBAP_OUTGOING = 56;
-
-    public static final int UNPAIR = 100;
-    public static final int AUTO_CONNECT_PROFILES = 101;
-    public static final int TRANSITION_TO_STABLE = 102;
-    public static final int CONNECT_OTHER_PROFILES = 103;
-    private static final int CONNECTION_ACCESS_REQUEST_REPLY = 104;
-    private static final int CONNECTION_ACCESS_REQUEST_EXPIRY = 105;
-
-    public static final int CONNECT_OTHER_PROFILES_DELAY = 4000; // 4 secs
-    private static final int CONNECTION_ACCESS_REQUEST_EXPIRY_TIMEOUT = 7000; // 7 secs
-    private static final int CONNECTION_ACCESS_UNDEFINED = -1;
-    private static final long INIT_INCOMING_REJECT_TIMER = 1000; // 1 sec
-    private static final long MAX_INCOMING_REJECT_TIMER = 3600 * 1000 * 4; // 4 hours
-
-    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
-    private static final String ACCESS_AUTHORITY_CLASS =
-        "com.android.settings.bluetooth.BluetoothPermissionRequest";
-
-    private BondedDevice mBondedDevice = new BondedDevice();
-    private OutgoingHandsfree mOutgoingHandsfree = new OutgoingHandsfree();
-    private IncomingHandsfree mIncomingHandsfree = new IncomingHandsfree();
-    private IncomingA2dp mIncomingA2dp = new IncomingA2dp();
-    private OutgoingA2dp mOutgoingA2dp = new OutgoingA2dp();
-    private OutgoingHid mOutgoingHid = new OutgoingHid();
-    private IncomingHid mIncomingHid = new IncomingHid();
-
-    private Context mContext;
-    private BluetoothService mService;
-    private BluetoothA2dpService mA2dpService;
-    private BluetoothHeadset  mHeadsetService;
-    private BluetoothPbap     mPbapService;
-    private PbapServiceListener mPbap;
-    private BluetoothAdapter mAdapter;
-    private boolean mPbapServiceConnected;
-    private boolean mAutoConnectionPending;
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-
-    private BluetoothDevice mDevice;
-    private int mHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
-    private int mA2dpState = BluetoothProfile.STATE_DISCONNECTED;
-    private long mIncomingRejectTimer;
-    private boolean mConnectionAccessReplyReceived = false;
-    private Pair<Integer, String> mIncomingConnections;
-    private PowerManager.WakeLock mWakeLock;
-    private PowerManager mPowerManager;
-    private boolean mPairingRequestRcvd = false;
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            if (device == null || !device.equals(mDevice)) return;
-
-            if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                // We trust this device now
-                if (newState == BluetoothHeadset.STATE_CONNECTED) {
-                    setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
-                }
-                mA2dpState = newState;
-                if (oldState == BluetoothA2dp.STATE_CONNECTED &&
-                    newState == BluetoothA2dp.STATE_DISCONNECTED) {
-                    sendMessage(DISCONNECT_A2DP_INCOMING);
-                }
-                if (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                // We trust this device now
-                if (newState == BluetoothHeadset.STATE_CONNECTED) {
-                    setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
-                }
-                mHeadsetState = newState;
-                if (oldState == BluetoothHeadset.STATE_CONNECTED &&
-                    newState == BluetoothHeadset.STATE_DISCONNECTED) {
-                    sendMessage(DISCONNECT_HFP_INCOMING);
-                }
-                if (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                int oldState =
-                    intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                // We trust this device now
-                if (newState == BluetoothHeadset.STATE_CONNECTED) {
-                    setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
-                }
-                if (oldState == BluetoothProfile.STATE_CONNECTED &&
-                    newState == BluetoothProfile.STATE_DISCONNECTED) {
-                    sendMessage(DISCONNECT_HID_INCOMING);
-                }
-                if (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
-                // This is technically not needed, but we can get stuck sometimes.
-                // For example, if incoming A2DP fails, we are not informed by Bluez
-                sendMessage(TRANSITION_TO_STABLE);
-            } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
-                mWakeLock.release();
-                int val = intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
-                                             BluetoothDevice.CONNECTION_ACCESS_NO);
-                Message msg = obtainMessage(CONNECTION_ACCESS_REQUEST_REPLY);
-                msg.arg1 = val;
-                sendMessage(msg);
-            } else if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
-                mPairingRequestRcvd = true;
-            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
-                        BluetoothDevice.ERROR);
-                if (state == BluetoothDevice.BOND_BONDED && mPairingRequestRcvd) {
-                    setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
-                    mPairingRequestRcvd = false;
-                } else if (state == BluetoothDevice.BOND_NONE) {
-                    mPairingRequestRcvd = false;
-                }
-            }
-        }
-    };
-
-    private boolean isPhoneDocked(BluetoothDevice autoConnectDevice) {
-        // This works only because these broadcast intents are "sticky"
-        Intent i = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
-        if (i != null) {
-            int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
-            if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                BluetoothDevice device = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                if (device != null && autoConnectDevice.equals(device)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public BluetoothDeviceProfileState(Context context, String address,
-          BluetoothService service, BluetoothA2dpService a2dpService, boolean setTrust) {
-        super(address);
-        mContext = context;
-        mDevice = new BluetoothDevice(address);
-        mService = service;
-        mA2dpService = a2dpService;
-
-        addState(mBondedDevice);
-        addState(mOutgoingHandsfree);
-        addState(mIncomingHandsfree);
-        addState(mIncomingA2dp);
-        addState(mOutgoingA2dp);
-        addState(mOutgoingHid);
-        addState(mIncomingHid);
-        setInitialState(mBondedDevice);
-
-        IntentFilter filter = new IntentFilter();
-        // Fine-grained state broadcasts
-        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
-        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
-        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
-        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mAdapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
-                                BluetoothProfile.HEADSET);
-        // TODO(): Convert PBAP to the new Profile APIs.
-        mPbap = new PbapServiceListener();
-
-        mIncomingConnections = mService.getIncomingState(address);
-        mIncomingRejectTimer = readTimerValue();
-        mPowerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK |
-                                              PowerManager.ACQUIRE_CAUSES_WAKEUP |
-                                              PowerManager.ON_AFTER_RELEASE, TAG);
-        mWakeLock.setReferenceCounted(false);
-
-        if (setTrust) {
-            setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
-        new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            synchronized(BluetoothDeviceProfileState.this) {
-                mHeadsetService = (BluetoothHeadset) proxy;
-                if (mAutoConnectionPending) {
-                    sendMessage(AUTO_CONNECT_PROFILES);
-                    mAutoConnectionPending = false;
-                }
-            }
-        }
-        public void onServiceDisconnected(int profile) {
-            synchronized(BluetoothDeviceProfileState.this) {
-                mHeadsetService = null;
-            }
-        }
-    };
-
-    private class PbapServiceListener implements BluetoothPbap.ServiceListener {
-        public PbapServiceListener() {
-            mPbapService = new BluetoothPbap(mContext, this);
-        }
-        public void onServiceConnected() {
-            synchronized(BluetoothDeviceProfileState.this) {
-                mPbapServiceConnected = true;
-            }
-        }
-        public void onServiceDisconnected() {
-            synchronized(BluetoothDeviceProfileState.this) {
-                mPbapServiceConnected = false;
-            }
-        }
-    }
-
-    @Override
-    protected void onQuitting() {
-        mContext.unregisterReceiver(mBroadcastReceiver);
-        mBroadcastReceiver = null;
-        mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
-        mBluetoothProfileServiceListener = null;
-        mOutgoingHandsfree = null;
-        mPbap = null;
-        mPbapService.close();
-        mPbapService = null;
-        mIncomingHid = null;
-        mOutgoingHid = null;
-        mIncomingHandsfree = null;
-        mOutgoingHandsfree = null;
-        mIncomingA2dp = null;
-        mOutgoingA2dp = null;
-        mBondedDevice = null;
-    }
-
-    private class BondedDevice extends State {
-        @Override
-        public void enter() {
-            Log.i(TAG, "Entering ACL Connected state with: " + getCurrentMessage().what);
-            Message m = new Message();
-            m.copyFrom(getCurrentMessage());
-            sendMessageAtFrontOfQueue(m);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            log("ACL Connected State -> Processing Message: " + message.what);
-            switch(message.what) {
-                case CONNECT_HFP_OUTGOING:
-                case DISCONNECT_HFP_OUTGOING:
-                    transitionTo(mOutgoingHandsfree);
-                    break;
-                case CONNECT_HFP_INCOMING:
-                    transitionTo(mIncomingHandsfree);
-                    break;
-                case DISCONNECT_HFP_INCOMING:
-                    transitionTo(mIncomingHandsfree);
-                    break;
-                case CONNECT_A2DP_OUTGOING:
-                case DISCONNECT_A2DP_OUTGOING:
-                    transitionTo(mOutgoingA2dp);
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                case DISCONNECT_A2DP_INCOMING:
-                    transitionTo(mIncomingA2dp);
-                    break;
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    transitionTo(mOutgoingHid);
-                    break;
-                case CONNECT_HID_INCOMING:
-                case DISCONNECT_HID_INCOMING:
-                    transitionTo(mIncomingHid);
-                    break;
-                case DISCONNECT_PBAP_OUTGOING:
-                    processCommand(DISCONNECT_PBAP_OUTGOING);
-                    break;
-                case UNPAIR:
-                    if (mHeadsetState != BluetoothHeadset.STATE_DISCONNECTED) {
-                        sendMessage(DISCONNECT_HFP_OUTGOING);
-                        deferMessage(message);
-                        break;
-                    } else if (mA2dpState != BluetoothA2dp.STATE_DISCONNECTED) {
-                        sendMessage(DISCONNECT_A2DP_OUTGOING);
-                        deferMessage(message);
-                        break;
-                    } else if (mService.getInputDeviceConnectionState(mDevice) !=
-                            BluetoothInputDevice.STATE_DISCONNECTED) {
-                        sendMessage(DISCONNECT_HID_OUTGOING);
-                        deferMessage(message);
-                        break;
-                    }
-                    processCommand(UNPAIR);
-                    break;
-                case AUTO_CONNECT_PROFILES:
-                    if (isPhoneDocked(mDevice)) {
-                        // Don't auto connect to docks.
-                        break;
-                    } else {
-                        if (mHeadsetService == null) {
-                              mAutoConnectionPending = true;
-                        } else if (mHeadsetService.getPriority(mDevice) ==
-                              BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
-                              mHeadsetService.getDevicesMatchingConnectionStates(
-                                  new int[] {BluetoothProfile.STATE_CONNECTED,
-                                             BluetoothProfile.STATE_CONNECTING,
-                                             BluetoothProfile.STATE_DISCONNECTING}).size() == 0) {
-                            mHeadsetService.connect(mDevice);
-                        }
-                        if (mA2dpService != null &&
-                              mA2dpService.getPriority(mDevice) ==
-                              BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
-                              mA2dpService.getDevicesMatchingConnectionStates(
-                                  new int[] {BluetoothA2dp.STATE_CONNECTED,
-                                             BluetoothProfile.STATE_CONNECTING,
-                                             BluetoothProfile.STATE_DISCONNECTING}).size() == 0) {
-                            mA2dpService.connect(mDevice);
-                        }
-                        if (mService.getInputDevicePriority(mDevice) ==
-                              BluetoothInputDevice.PRIORITY_AUTO_CONNECT) {
-                            mService.connectInputDevice(mDevice);
-                        }
-                    }
-                    break;
-                case CONNECT_OTHER_PROFILES:
-                    if (isPhoneDocked(mDevice)) {
-                       break;
-                    }
-                    if (message.arg1 == CONNECT_A2DP_OUTGOING) {
-                        if (mA2dpService != null &&
-                            mA2dpService.getConnectedDevices().size() == 0) {
-                            Log.i(TAG, "A2dp:Connect Other Profiles");
-                            mA2dpService.connect(mDevice);
-                        }
-                    } else if (message.arg1 == CONNECT_HFP_OUTGOING) {
-                        if (mHeadsetService == null) {
-                            deferMessage(message);
-                        } else {
-                            if (mHeadsetService.getConnectedDevices().size() == 0) {
-                                Log.i(TAG, "Headset:Connect Other Profiles");
-                                mHeadsetService.connect(mDevice);
-                            }
-                        }
-                    }
-                    break;
-                case TRANSITION_TO_STABLE:
-                    // ignore.
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private class OutgoingHandsfree extends State {
-        private boolean mStatus = false;
-        private int mCommand;
-
-        @Override
-        public void enter() {
-            Log.i(TAG, "Entering OutgoingHandsfree state with: " + getCurrentMessage().what);
-            mCommand = getCurrentMessage().what;
-            if (mCommand != CONNECT_HFP_OUTGOING &&
-                mCommand != DISCONNECT_HFP_OUTGOING) {
-                Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand);
-            }
-            mStatus = processCommand(mCommand);
-            if (!mStatus) {
-                sendMessage(TRANSITION_TO_STABLE);
-                mService.sendProfileStateMessage(BluetoothProfileState.HFP,
-                                                 BluetoothProfileState.TRANSITION_TO_STABLE);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("OutgoingHandsfree State -> Processing Message: " + message.what);
-            Message deferMsg = new Message();
-            int command = message.what;
-            switch(command) {
-                case CONNECT_HFP_OUTGOING:
-                    if (command != mCommand) {
-                        // Disconnect followed by a connect - defer
-                        deferMessage(message);
-                    }
-                    break;
-                case CONNECT_HFP_INCOMING:
-                    if (mCommand == CONNECT_HFP_OUTGOING) {
-                        // Cancel outgoing connect, accept incoming
-                        cancelCommand(CONNECT_HFP_OUTGOING);
-                        transitionTo(mIncomingHandsfree);
-                    } else {
-                        // We have done the disconnect but we are not
-                        // sure which state we are in at this point.
-                        deferMessage(message);
-                    }
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                    // accept incoming A2DP, retry HFP_OUTGOING
-                    transitionTo(mIncomingA2dp);
-
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case CONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_OUTGOING:
-                    if (mCommand == CONNECT_HFP_OUTGOING) {
-                        // Cancel outgoing connect
-                        cancelCommand(CONNECT_HFP_OUTGOING);
-                        processCommand(DISCONNECT_HFP_OUTGOING);
-                    }
-                    // else ignore
-                    break;
-                case DISCONNECT_HFP_INCOMING:
-                    // When this happens the socket would be closed and the headset
-                    // state moved to DISCONNECTED, cancel the outgoing thread.
-                    // if it still is in CONNECTING state
-                    cancelCommand(CONNECT_HFP_OUTGOING);
-                    break;
-                case DISCONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_A2DP_INCOMING:
-                    // Bluez will handle the disconnect. If because of this the outgoing
-                    // handsfree connection has failed, then retry.
-                    if (mStatus) {
-                       deferMsg.what = mCommand;
-                       deferMessage(deferMsg);
-                    }
-                    break;
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HID_INCOMING:
-                    transitionTo(mIncomingHid);
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case DISCONNECT_HID_INCOMING:
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break; // ignore
-                case DISCONNECT_PBAP_OUTGOING:
-                case UNPAIR:
-                case AUTO_CONNECT_PROFILES:
-                case CONNECT_OTHER_PROFILES:
-                    deferMessage(message);
-                    break;
-                case TRANSITION_TO_STABLE:
-                    transitionTo(mBondedDevice);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private class IncomingHandsfree extends State {
-        private boolean mStatus = false;
-        private int mCommand;
-
-        @Override
-        public void enter() {
-            Log.i(TAG, "Entering IncomingHandsfree state with: " + getCurrentMessage().what);
-            mCommand = getCurrentMessage().what;
-            if (mCommand != CONNECT_HFP_INCOMING &&
-                mCommand != DISCONNECT_HFP_INCOMING) {
-                Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand);
-            }
-            mStatus = processCommand(mCommand);
-            if (!mStatus) {
-                sendMessage(TRANSITION_TO_STABLE);
-                mService.sendProfileStateMessage(BluetoothProfileState.HFP,
-                                                 BluetoothProfileState.TRANSITION_TO_STABLE);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("IncomingHandsfree State -> Processing Message: " + message.what);
-            switch(message.what) {
-                case CONNECT_HFP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HFP_INCOMING:
-                    // Ignore
-                    Log.e(TAG, "Error: Incoming connection with a pending incoming connection");
-                    break;
-                case CONNECTION_ACCESS_REQUEST_REPLY:
-                    int val = message.arg1;
-                    mConnectionAccessReplyReceived = true;
-                    boolean value = false;
-                    if (val == BluetoothDevice.CONNECTION_ACCESS_YES) {
-                        value = true;
-                    }
-                    setTrust(val);
-
-                    handleIncomingConnection(CONNECT_HFP_INCOMING, value);
-                    break;
-                case CONNECTION_ACCESS_REQUEST_EXPIRY:
-                    if (!mConnectionAccessReplyReceived) {
-                        handleIncomingConnection(CONNECT_HFP_INCOMING, false);
-                        sendConnectionAccessRemovalIntent();
-                        sendMessage(TRANSITION_TO_STABLE);
-                    }
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                    // Serialize the commands.
-                    deferMessage(message);
-                    break;
-                case CONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_OUTGOING:
-                    // We don't know at what state we are in the incoming HFP connection state.
-                    // We can be changing from DISCONNECTED to CONNECTING, or
-                    // from CONNECTING to CONNECTED, so serializing this command is
-                    // the safest option.
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_INCOMING:
-                    // Nothing to do here, we will already be DISCONNECTED
-                    // by this point.
-                    break;
-                case DISCONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_A2DP_INCOMING:
-                    // Bluez handles incoming A2DP disconnect.
-                    // If this causes incoming HFP to fail, it is more of a headset problem
-                    // since both connections are incoming ones.
-                    break;
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HID_INCOMING:
-                case DISCONNECT_HID_INCOMING:
-                     break; // ignore
-                case DISCONNECT_PBAP_OUTGOING:
-                case UNPAIR:
-                case AUTO_CONNECT_PROFILES:
-                case CONNECT_OTHER_PROFILES:
-                    deferMessage(message);
-                    break;
-                case TRANSITION_TO_STABLE:
-                    transitionTo(mBondedDevice);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private class OutgoingA2dp extends State {
-        private boolean mStatus = false;
-        private int mCommand;
-
-        @Override
-        public void enter() {
-            Log.i(TAG, "Entering OutgoingA2dp state with: " + getCurrentMessage().what);
-            mCommand = getCurrentMessage().what;
-            if (mCommand != CONNECT_A2DP_OUTGOING &&
-                mCommand != DISCONNECT_A2DP_OUTGOING) {
-                Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand);
-            }
-            mStatus = processCommand(mCommand);
-            if (!mStatus) {
-                sendMessage(TRANSITION_TO_STABLE);
-                mService.sendProfileStateMessage(BluetoothProfileState.A2DP,
-                                                 BluetoothProfileState.TRANSITION_TO_STABLE);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("OutgoingA2dp State->Processing Message: " + message.what);
-            Message deferMsg = new Message();
-            switch(message.what) {
-                case CONNECT_HFP_OUTGOING:
-                    processCommand(CONNECT_HFP_OUTGOING);
-
-                    // Don't cancel A2DP outgoing as there is no guarantee it
-                    // will get canceled.
-                    // It might already be connected but we might not have got the
-                    // A2DP_SINK_STATE_CHANGE. Hence, no point disconnecting here.
-                    // The worst case, the connection will fail, retry.
-                    // The same applies to Disconnecting an A2DP connection.
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case CONNECT_HFP_INCOMING:
-                    processCommand(CONNECT_HFP_INCOMING);
-
-                    // Don't cancel A2DP outgoing as there is no guarantee
-                    // it will get canceled.
-                    // The worst case, the connection will fail, retry.
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                    // Bluez will take care of conflicts between incoming and outgoing
-                    // connections.
-                    transitionTo(mIncomingA2dp);
-                    break;
-                case CONNECT_A2DP_OUTGOING:
-                    // Ignore
-                    break;
-                case DISCONNECT_HFP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_INCOMING:
-                    // At this point, we are already disconnected
-                    // with HFP. Sometimes A2DP connection can
-                    // fail due to the disconnection of HFP. So add a retry
-                    // for the A2DP.
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case DISCONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_A2DP_INCOMING:
-                    // Ignore, will be handled by Bluez
-                    break;
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HID_INCOMING:
-                    transitionTo(mIncomingHid);
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case DISCONNECT_HID_INCOMING:
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break; // ignore
-                case DISCONNECT_PBAP_OUTGOING:
-                case UNPAIR:
-                case AUTO_CONNECT_PROFILES:
-                case CONNECT_OTHER_PROFILES:
-                    deferMessage(message);
-                    break;
-                case TRANSITION_TO_STABLE:
-                    transitionTo(mBondedDevice);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private class IncomingA2dp extends State {
-        private boolean mStatus = false;
-        private int mCommand;
-
-        @Override
-        public void enter() {
-            Log.i(TAG, "Entering IncomingA2dp state with: " + getCurrentMessage().what);
-            mCommand = getCurrentMessage().what;
-            if (mCommand != CONNECT_A2DP_INCOMING &&
-                mCommand != DISCONNECT_A2DP_INCOMING) {
-                Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand);
-            }
-            mStatus = processCommand(mCommand);
-            if (!mStatus) {
-                sendMessage(TRANSITION_TO_STABLE);
-                mService.sendProfileStateMessage(BluetoothProfileState.A2DP,
-                                                 BluetoothProfileState.TRANSITION_TO_STABLE);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("IncomingA2dp State->Processing Message: " + message.what);
-            switch(message.what) {
-                case CONNECT_HFP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HFP_INCOMING:
-                    // Shouldn't happen, but serialize the commands.
-                    deferMessage(message);
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                    // ignore
-                    break;
-                case CONNECTION_ACCESS_REQUEST_REPLY:
-                    int val = message.arg1;
-                    mConnectionAccessReplyReceived = true;
-                    boolean value = false;
-                    if (val == BluetoothDevice.CONNECTION_ACCESS_YES) {
-                        value = true;
-                    }
-                    setTrust(val);
-                    handleIncomingConnection(CONNECT_A2DP_INCOMING, value);
-                    break;
-                case CONNECTION_ACCESS_REQUEST_EXPIRY:
-                    // The check protects the race condition between REQUEST_REPLY
-                    // and the timer expiry.
-                    if (!mConnectionAccessReplyReceived) {
-                        handleIncomingConnection(CONNECT_A2DP_INCOMING, false);
-                        sendConnectionAccessRemovalIntent();
-                        sendMessage(TRANSITION_TO_STABLE);
-                    }
-                    break;
-                case CONNECT_A2DP_OUTGOING:
-                    // Defer message and retry
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_HFP_INCOMING:
-                    // Shouldn't happen but if does, we can handle it.
-                    // Depends if the headset can handle it.
-                    // Incoming A2DP will be handled by Bluez, Disconnect HFP
-                    // the socket would have already been closed.
-                    // ignore
-                    break;
-                case DISCONNECT_A2DP_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case DISCONNECT_A2DP_INCOMING:
-                    // Ignore, will be handled by Bluez
-                    break;
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    deferMessage(message);
-                    break;
-                case CONNECT_HID_INCOMING:
-                case DISCONNECT_HID_INCOMING:
-                     break; // ignore
-                case DISCONNECT_PBAP_OUTGOING:
-                case UNPAIR:
-                case AUTO_CONNECT_PROFILES:
-                case CONNECT_OTHER_PROFILES:
-                    deferMessage(message);
-                    break;
-                case TRANSITION_TO_STABLE:
-                    transitionTo(mBondedDevice);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-
-    private class OutgoingHid extends State {
-        private boolean mStatus = false;
-        private int mCommand;
-
-        @Override
-        public void enter() {
-            log("Entering OutgoingHid state with: " + getCurrentMessage().what);
-            mCommand = getCurrentMessage().what;
-            if (mCommand != CONNECT_HID_OUTGOING &&
-                mCommand != DISCONNECT_HID_OUTGOING) {
-                Log.e(TAG, "Error: OutgoingHid state with command:" + mCommand);
-            }
-            mStatus = processCommand(mCommand);
-            if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("OutgoingHid State->Processing Message: " + message.what);
-            Message deferMsg = new Message();
-            switch(message.what) {
-                // defer all outgoing messages
-                case CONNECT_HFP_OUTGOING:
-                case CONNECT_A2DP_OUTGOING:
-                case CONNECT_HID_OUTGOING:
-                case DISCONNECT_HFP_OUTGOING:
-                case DISCONNECT_A2DP_OUTGOING:
-                case DISCONNECT_HID_OUTGOING:
-                    deferMessage(message);
-                    break;
-
-                case CONNECT_HFP_INCOMING:
-                    transitionTo(mIncomingHandsfree);
-                    break;
-                case CONNECT_A2DP_INCOMING:
-                    transitionTo(mIncomingA2dp);
-
-                    // Don't cancel HID outgoing as there is no guarantee it
-                    // will get canceled.
-                    // It might already be connected but we might not have got the
-                    // INPUT_DEVICE_STATE_CHANGE. Hence, no point disconnecting here.
-                    // The worst case, the connection will fail, retry.
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case CONNECT_HID_INCOMING:
-                  // Bluez will take care of the conflicts
-                    transitionTo(mIncomingHid);
-                    break;
-
-                case DISCONNECT_HFP_INCOMING:
-                case DISCONNECT_A2DP_INCOMING:
-                    // At this point, we are already disconnected
-                    // with HFP. Sometimes HID connection can
-                    // fail due to the disconnection of HFP. So add a retry
-                    // for the HID.
-                    if (mStatus) {
-                        deferMsg.what = mCommand;
-                        deferMessage(deferMsg);
-                    }
-                    break;
-                case DISCONNECT_HID_INCOMING:
-                    // Ignore, will be handled by Bluez
-                    break;
-                case DISCONNECT_PBAP_OUTGOING:
-                case UNPAIR:
-                case AUTO_CONNECT_PROFILES:
-                    deferMessage(message);
-                    break;
-                case TRANSITION_TO_STABLE:
-                    transitionTo(mBondedDevice);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-  private class IncomingHid extends State {
-      private boolean mStatus = false;
-      private int mCommand;
-
-      @Override
-    public void enter() {
-          log("Entering IncomingHid state with: " + getCurrentMessage().what);
-          mCommand = getCurrentMessage().what;
-          if (mCommand != CONNECT_HID_INCOMING &&
-              mCommand != DISCONNECT_HID_INCOMING) {
-              Log.e(TAG, "Error: IncomingHid state with command:" + mCommand);
-          }
-          mStatus = processCommand(mCommand);
-          if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
-      }
-
-      @Override
-    public boolean processMessage(Message message) {
-          log("IncomingHid State->Processing Message: " + message.what);
-          Message deferMsg = new Message();
-          switch(message.what) {
-              case CONNECT_HFP_OUTGOING:
-              case CONNECT_HFP_INCOMING:
-              case DISCONNECT_HFP_OUTGOING:
-              case CONNECT_A2DP_INCOMING:
-              case CONNECT_A2DP_OUTGOING:
-              case DISCONNECT_A2DP_OUTGOING:
-              case CONNECT_HID_OUTGOING:
-              case CONNECT_HID_INCOMING:
-              case DISCONNECT_HID_OUTGOING:
-                  deferMessage(message);
-                  break;
-              case CONNECTION_ACCESS_REQUEST_REPLY:
-                  mConnectionAccessReplyReceived = true;
-                  int val = message.arg1;
-                  setTrust(val);
-                  handleIncomingConnection(CONNECT_HID_INCOMING,
-                      val == BluetoothDevice.CONNECTION_ACCESS_YES);
-                  break;
-              case CONNECTION_ACCESS_REQUEST_EXPIRY:
-                  if (!mConnectionAccessReplyReceived) {
-                      handleIncomingConnection(CONNECT_HID_INCOMING, false);
-                      sendConnectionAccessRemovalIntent();
-                      sendMessage(TRANSITION_TO_STABLE);
-                  }
-                  break;
-              case DISCONNECT_HFP_INCOMING:
-                  // Shouldn't happen but if does, we can handle it.
-                  // Depends if the headset can handle it.
-                  // Incoming HID will be handled by Bluez, Disconnect HFP
-                  // the socket would have already been closed.
-                  // ignore
-                  break;
-              case DISCONNECT_HID_INCOMING:
-              case DISCONNECT_A2DP_INCOMING:
-                  // Ignore, will be handled by Bluez
-                  break;
-              case DISCONNECT_PBAP_OUTGOING:
-              case UNPAIR:
-              case AUTO_CONNECT_PROFILES:
-                  deferMessage(message);
-                  break;
-              case TRANSITION_TO_STABLE:
-                  transitionTo(mBondedDevice);
-                  break;
-              default:
-                  return NOT_HANDLED;
-          }
-          return HANDLED;
-      }
-  }
-
-
-    synchronized void cancelCommand(int command) {
-        if (command == CONNECT_HFP_OUTGOING ) {
-            // Cancel the outgoing thread.
-            if (mHeadsetService != null) {
-                mHeadsetService.cancelConnectThread();
-            }
-            // HeadsetService is down. Phone process most likely crashed.
-            // The thread would have got killed.
-        }
-    }
-
-    synchronized void deferProfileServiceMessage(int command) {
-        Message msg = new Message();
-        msg.what = command;
-        deferMessage(msg);
-    }
-
-    private void updateIncomingAllowedTimer() {
-        // Not doing a perfect exponential backoff because
-        // we want two different rates. For all practical
-        // purposes, this is good enough.
-        if (mIncomingRejectTimer == 0) mIncomingRejectTimer = INIT_INCOMING_REJECT_TIMER;
-
-        mIncomingRejectTimer *= 5;
-        if (mIncomingRejectTimer > MAX_INCOMING_REJECT_TIMER) {
-            mIncomingRejectTimer = MAX_INCOMING_REJECT_TIMER;
-        }
-        writeTimerValue(mIncomingRejectTimer);
-    }
-
-    private boolean handleIncomingConnection(int command, boolean accept) {
-        boolean ret = false;
-        Log.i(TAG, "handleIncomingConnection:" + command + ":" + accept);
-        switch (command) {
-            case CONNECT_HFP_INCOMING:
-                if (!accept) {
-                    ret = mHeadsetService.rejectIncomingConnect(mDevice);
-                    sendMessage(TRANSITION_TO_STABLE);
-                    updateIncomingAllowedTimer();
-                } else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) {
-                    writeTimerValue(0);
-                    ret =  mHeadsetService.acceptIncomingConnect(mDevice);
-                } else if (mHeadsetState == BluetoothHeadset.STATE_DISCONNECTED) {
-                    writeTimerValue(0);
-                    handleConnectionOfOtherProfiles(command);
-                    ret = mHeadsetService.createIncomingConnect(mDevice);
-                }
-                break;
-            case CONNECT_A2DP_INCOMING:
-                if (!accept) {
-                    ret = mA2dpService.allowIncomingConnect(mDevice, false);
-                    sendMessage(TRANSITION_TO_STABLE);
-                    updateIncomingAllowedTimer();
-                } else {
-                    writeTimerValue(0);
-                    ret = mA2dpService.allowIncomingConnect(mDevice, true);
-                    handleConnectionOfOtherProfiles(command);
-                }
-                break;
-            case CONNECT_HID_INCOMING:
-                if (!accept) {
-                    ret = mService.allowIncomingProfileConnect(mDevice, false);
-                    sendMessage(TRANSITION_TO_STABLE);
-                    updateIncomingAllowedTimer();
-                } else {
-                    writeTimerValue(0);
-                    ret = mService.allowIncomingProfileConnect(mDevice, true);
-                }
-                break;
-            default:
-                Log.e(TAG, "Waiting for incoming connection but state changed to:" + command);
-                break;
-       }
-       return ret;
-    }
-
-    private void sendConnectionAccessIntent() {
-        mConnectionAccessReplyReceived = false;
-
-        if (!mPowerManager.isScreenOn()) mWakeLock.acquire();
-
-        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
-        intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
-        intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
-                        BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-    }
-
-    private void sendConnectionAccessRemovalIntent() {
-        mWakeLock.release();
-        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-    }
-
-    private int getTrust() {
-        String address = mDevice.getAddress();
-        if (mIncomingConnections != null) return mIncomingConnections.first;
-        return CONNECTION_ACCESS_UNDEFINED;
-    }
-
-
-    private String getStringValue(long value) {
-        StringBuilder sbr = new StringBuilder();
-        sbr.append(Long.toString(System.currentTimeMillis()));
-        sbr.append("-");
-        sbr.append(Long.toString(value));
-        return sbr.toString();
-    }
-
-    private void setTrust(int value) {
-        String second;
-        if (mIncomingConnections == null) {
-            second = getStringValue(INIT_INCOMING_REJECT_TIMER);
-        } else {
-            second = mIncomingConnections.second;
-        }
-
-        mIncomingConnections = new Pair(value, second);
-        mService.writeIncomingConnectionState(mDevice.getAddress(), mIncomingConnections);
-    }
-
-    private void writeTimerValue(long value) {
-        Integer first;
-        if (mIncomingConnections == null) {
-            first = CONNECTION_ACCESS_UNDEFINED;
-        } else {
-            first = mIncomingConnections.first;
-        }
-        mIncomingConnections = new Pair(first, getStringValue(value));
-        mService.writeIncomingConnectionState(mDevice.getAddress(), mIncomingConnections);
-    }
-
-    private long readTimerValue() {
-        if (mIncomingConnections == null)
-            return 0;
-        String value = mIncomingConnections.second;
-        String[] splits = value.split("-");
-        if (splits != null && splits.length == 2) {
-            return Long.parseLong(splits[1]);
-        }
-        return 0;
-    }
-
-    private boolean readIncomingAllowedValue() {
-        if (readTimerValue() == 0) return true;
-        String value = mIncomingConnections.second;
-        String[] splits = value.split("-");
-        if (splits != null && splits.length == 2) {
-            long val1 = Long.parseLong(splits[0]);
-            long val2 = Long.parseLong(splits[1]);
-            if (val1 + val2 <= System.currentTimeMillis()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    synchronized boolean processCommand(int command) {
-        log("Processing command:" + command);
-        switch(command) {
-            case  CONNECT_HFP_OUTGOING:
-                if (mHeadsetService == null) {
-                    deferProfileServiceMessage(command);
-                } else {
-                    return mHeadsetService.connectHeadsetInternal(mDevice);
-                }
-                break;
-            case CONNECT_HFP_INCOMING:
-                if (mHeadsetService == null) {
-                    deferProfileServiceMessage(command);
-                } else {
-                    processIncomingConnectCommand(command);
-                    return true;
-                }
-                break;
-            case CONNECT_A2DP_OUTGOING:
-                if (mA2dpService != null) {
-                    return mA2dpService.connectSinkInternal(mDevice);
-                }
-                break;
-            case CONNECT_A2DP_INCOMING:
-                processIncomingConnectCommand(command);
-                return true;
-            case CONNECT_HID_OUTGOING:
-                return mService.connectInputDeviceInternal(mDevice);
-            case CONNECT_HID_INCOMING:
-                processIncomingConnectCommand(command);
-                return true;
-            case DISCONNECT_HFP_OUTGOING:
-                if (mHeadsetService == null) {
-                    deferProfileServiceMessage(command);
-                } else {
-                    // Disconnect PBAP
-                    // TODO(): Add PBAP to the state machine.
-                    Message m = new Message();
-                    m.what = DISCONNECT_PBAP_OUTGOING;
-                    deferMessage(m);
-                    if (mHeadsetService.getPriority(mDevice) ==
-                        BluetoothHeadset.PRIORITY_AUTO_CONNECT) {
-                        mHeadsetService.setPriority(mDevice, BluetoothHeadset.PRIORITY_ON);
-                    }
-                    return mHeadsetService.disconnectHeadsetInternal(mDevice);
-                }
-                break;
-            case DISCONNECT_HFP_INCOMING:
-                // ignore
-                return true;
-            case DISCONNECT_A2DP_INCOMING:
-                // ignore
-                return true;
-            case DISCONNECT_A2DP_OUTGOING:
-                if (mA2dpService != null) {
-                    if (mA2dpService.getPriority(mDevice) ==
-                        BluetoothA2dp.PRIORITY_AUTO_CONNECT) {
-                        mA2dpService.setPriority(mDevice, BluetoothHeadset.PRIORITY_ON);
-                    }
-                    return mA2dpService.disconnectSinkInternal(mDevice);
-                }
-                break;
-            case DISCONNECT_HID_INCOMING:
-                // ignore
-                return true;
-            case DISCONNECT_HID_OUTGOING:
-                if (mService.getInputDevicePriority(mDevice) ==
-                    BluetoothInputDevice.PRIORITY_AUTO_CONNECT) {
-                    mService.setInputDevicePriority(mDevice, BluetoothInputDevice.PRIORITY_ON);
-                }
-                return mService.disconnectInputDeviceInternal(mDevice);
-            case DISCONNECT_PBAP_OUTGOING:
-                if (!mPbapServiceConnected) {
-                    deferProfileServiceMessage(command);
-                } else {
-                    return mPbapService.disconnect();
-                }
-                break;
-            case UNPAIR:
-                writeTimerValue(INIT_INCOMING_REJECT_TIMER);
-                setTrust(CONNECTION_ACCESS_UNDEFINED);
-                return mService.removeBondInternal(mDevice.getAddress());
-            default:
-                Log.e(TAG, "Error: Unknown Command");
-        }
-        return false;
-    }
-
-    private void processIncomingConnectCommand(int command) {
-        // Check if device is already trusted
-        int access = getTrust();
-        if (access == BluetoothDevice.CONNECTION_ACCESS_YES) {
-            handleIncomingConnection(command, true);
-        } else if (access == BluetoothDevice.CONNECTION_ACCESS_NO &&
-                   !readIncomingAllowedValue()) {
-            handleIncomingConnection(command, false);
-        } else {
-            sendConnectionAccessIntent();
-            Message msg = obtainMessage(CONNECTION_ACCESS_REQUEST_EXPIRY);
-            sendMessageDelayed(msg,
-                               CONNECTION_ACCESS_REQUEST_EXPIRY_TIMEOUT);
-        }
-    }
-
-    private void handleConnectionOfOtherProfiles(int command) {
-        // The white paper recommendations mentions that when there is a
-        // link loss, it is the responsibility of the remote device to connect.
-        // Many connect only 1 profile - and they connect the second profile on
-        // some user action (like play being pressed) and so we need this code.
-        // Auto Connect code only connects to the last connected device - which
-        // is useful in cases like when the phone reboots. But consider the
-        // following case:
-        // User is connected to the car's phone and  A2DP profile.
-        // User comes to the desk  and places the phone in the dock
-        // (or any speaker or music system or even another headset) and thus
-        // gets connected to the A2DP profile.  User goes back to the car.
-        // Ideally the car's system is supposed to send incoming connections
-        // from both Handsfree and A2DP profile. But they don't. The Auto
-        // connect code, will not work here because we only auto connect to the
-        // last connected device for that profile which in this case is the dock.
-        // Now suppose a user is using 2 headsets simultaneously, one for the
-        // phone profile one for the A2DP profile. If this is the use case, we
-        // expect the user to use the preference to turn off the A2DP profile in
-        // the Settings screen for the first headset. Else, after link loss,
-        // there can be an incoming connection from the first headset which
-        // might result in the connection of the A2DP profile (if the second
-        // headset is slower) and thus the A2DP profile on the second headset
-        // will never get connected.
-        //
-        // TODO(): Handle other profiles here.
-        switch (command) {
-            case CONNECT_HFP_INCOMING:
-                // Connect A2DP if there is no incoming connection
-                // If the priority is OFF - don't auto connect.
-                if (mA2dpService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON ||
-                        mA2dpService.getPriority(mDevice) ==
-                            BluetoothProfile.PRIORITY_AUTO_CONNECT) {
-                    Message msg = new Message();
-                    msg.what = CONNECT_OTHER_PROFILES;
-                    msg.arg1 = CONNECT_A2DP_OUTGOING;
-                    sendMessageDelayed(msg, CONNECT_OTHER_PROFILES_DELAY);
-                }
-                break;
-            case CONNECT_A2DP_INCOMING:
-                // This is again against spec. HFP incoming connections should be made
-                // before A2DP, so we should not hit this case. But many devices
-                // don't follow this.
-                if (mHeadsetService != null &&
-                    (mHeadsetService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON ||
-                        mHeadsetService.getPriority(mDevice) ==
-                            BluetoothProfile.PRIORITY_AUTO_CONNECT)) {
-                    Message msg = new Message();
-                    msg.what = CONNECT_OTHER_PROFILES;
-                    msg.arg1 = CONNECT_HFP_OUTGOING;
-                    sendMessageDelayed(msg, CONNECT_OTHER_PROFILES_DELAY);
-                }
-                break;
-            default:
-                break;
-        }
-
-    }
-
-    /*package*/ BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Quit the state machine, only to be called by BluetoothService.
-     *
-     * @hide
-     */
-    public void doQuit() {
-        this.quit();
-    }
-
-    private void log(String message) {
-        if (DBG) {
-            Log.i(TAG, "Device:" + mDevice + " Message:" + message);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
old mode 100644
new mode 100755
index 2bbf008..75dfe9d
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -45,7 +45,7 @@
  */
 public final class BluetoothHeadset implements BluetoothProfile {
     private static final String TAG = "BluetoothHeadset";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Intent used to broadcast the change in connection state of the Headset
@@ -219,7 +219,38 @@
     private Context mContext;
     private ServiceListener mServiceListener;
     private IBluetoothHeadset mService;
-    BluetoothAdapter mAdapter;
+    private BluetoothAdapter mAdapter;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (DBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (DBG) Log.d(TAG,"Binding service...");
+                                    if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
+                                        Log.e(TAG, "Could not bind to Bluetooth Headset Service");
+                                    }
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
 
     /**
      * Create a BluetoothHeadset proxy object.
@@ -228,6 +259,16 @@
         mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
         if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Service");
         }
@@ -239,11 +280,27 @@
      * results once close() has been called. Multiple invocations of close()
      * are ok.
      */
-    /*package*/ synchronized void close() {
+    /*package*/ void close() {
         if (DBG) log("close()");
-        if (mConnection != null) {
-            mContext.unbindService(mConnection);
-            mConnection = null;
+
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
         }
         mServiceListener = null;
     }
@@ -398,7 +455,8 @@
         if (mService != null && isEnabled() &&
             isValidDevice(device)) {
             if (priority != BluetoothProfile.PRIORITY_OFF &&
-                priority != BluetoothProfile.PRIORITY_ON) {
+                priority != BluetoothProfile.PRIORITY_ON &&
+                priority != BluetoothProfile.PRIORITY_AUTO_CONNECT) {
               return false;
             }
             try {
@@ -562,25 +620,6 @@
     }
 
     /**
-     * Cancel the outgoing connection.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    public boolean cancelConnectThread() {
-        if (DBG) log("cancelConnectThread");
-        if (mService != null && isEnabled()) {
-            try {
-                return mService.cancelConnectThread();
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        }
-        return false;
-    }
-
-    /**
      * Accept the incoming connection.
      * Note: This is an internal function and shouldn't be exposed
      *
@@ -600,25 +639,6 @@
     }
 
     /**
-     * Create the connect thread for the incoming connection.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    public boolean createIncomingConnect(BluetoothDevice device) {
-        if (DBG) log("createIncomingConnect");
-        if (mService != null && isEnabled()) {
-            try {
-                return mService.createIncomingConnect(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        }
-        return false;
-    }
-
-    /**
      * Reject the incoming connection.
      * @hide
      */
@@ -636,63 +656,6 @@
     }
 
     /**
-     * Connect to a Bluetooth Headset.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    public boolean connectHeadsetInternal(BluetoothDevice device) {
-        if (DBG) log("connectHeadsetInternal");
-        if (mService != null && isEnabled()) {
-            try {
-                return mService.connectHeadsetInternal(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        }
-        return false;
-    }
-
-    /**
-     * Disconnect a Bluetooth Headset.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    public boolean disconnectHeadsetInternal(BluetoothDevice device) {
-        if (DBG) log("disconnectHeadsetInternal");
-        if (mService != null && !isDisabled()) {
-            try {
-                 return mService.disconnectHeadsetInternal(device);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        }
-        return false;
-    }
-
-    /**
-     * Set the audio state of the Headset.
-     * Note: This is an internal function and shouldn't be exposed
-     *
-     * @hide
-     */
-    public boolean setAudioState(BluetoothDevice device, int state) {
-        if (DBG) log("setAudioState");
-        if (mService != null && !isDisabled()) {
-            try {
-                return mService.setAudioState(device, state);
-            } catch (RemoteException e) {Log.e(TAG, e.toString());}
-        } else {
-            Log.w(TAG, "Proxy not attached to service");
-            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
-        }
-        return false;
-    }
-
-    /**
      * Get the current audio state of the Headset.
      * Note: This is an internal function and shouldn't be exposed
      *
@@ -712,6 +675,75 @@
     }
 
     /**
+     * Check if Bluetooth SCO audio is connected.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @return true if SCO is connected,
+     *         false otherwise or on error
+     * @hide
+     */
+    public boolean isAudioOn() {
+        if (DBG) log("isAudioOn()");
+        if (mService != null && isEnabled()) {
+            try {
+              return mService.isAudioOn();
+            } catch (RemoteException e) {
+              Log.e(TAG,  Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+
+    }
+
+    /**
+     * Initiates a connection of headset audio.
+     * It setup SCO channel with remote connected headset device.
+     *
+     * @return true if successful
+     *         false if there was some error such as
+     *               there is no connected headset
+     * @hide
+     */
+    public boolean connectAudio() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.connectAudio();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Initiates a disconnection of headset audio.
+     * It tears down the SCO channel from remote headset device.
+     *
+     * @return true if successful
+     *         false if there was some error such as
+     *               there is no connected SCO channel
+     * @hide
+     */
+    public boolean disconnectAudio() {
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.disconnectAudio();
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
      * Initiates a SCO channel connection with the headset (if connected).
      * Also initiates a virtual voice call for Handsfree devices as many devices
      * do not accept SCO audio without a call.
@@ -760,6 +792,68 @@
         return false;
     }
 
+    /**
+     * Notify Headset of phone state change.
+     * This is a backdoor for phone app to call BluetoothHeadset since
+     * there is currently not a good way to get precise call state change outside
+     * of phone app.
+     *
+     * @hide
+     */
+    public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
+                                  int type) {
+        if (mService != null && isEnabled()) {
+            try {
+                mService.phoneStateChanged(numActive, numHeld, callState, number, type);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+    }
+
+    /**
+     * Notify Headset of phone roam state change.
+     * This is a backdoor for phone app to call BluetoothHeadset since
+     * there is currently not a good way to get roaming state change outside
+     * of phone app.
+     *
+     * @hide
+     */
+    public void roamChanged(boolean roaming) {
+        if (mService != null && isEnabled()) {
+            try {
+                mService.roamChanged(roaming);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+    }
+
+    /**
+     * Send Headset of CLCC response
+     *
+     * @hide
+     */
+    public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
+                             String number, int type) {
+        if (mService != null && isEnabled()) {
+            try {
+                mService.clccResponse(index, direction, status, mode, mpty, number, type);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+    }
+
     private ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index f850c02..4a0bc7e 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -16,7 +16,10 @@
 
 package android.bluetooth;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -54,7 +57,7 @@
  */
 public final class BluetoothHealth implements BluetoothProfile {
     private static final String TAG = "BluetoothHealth";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Health Profile Source Role - the health device.
@@ -94,6 +97,37 @@
     /** @hide */
     public static final int HEALTH_OPERATION_NOT_ALLOWED = 6005;
 
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (DBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (DBG) Log.d(TAG,"Binding service...");
+                                    if (!mContext.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
+                                        Log.e(TAG, "Could not bind to Bluetooth Health Service");
+                                    }
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
+
 
     /**
      * Register an application configuration that acts as a Health SINK.
@@ -427,35 +461,74 @@
     /** Health App Configuration un-registration failure */
     public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3;
 
+    private Context mContext;
     private ServiceListener mServiceListener;
-    private IBluetooth mService;
+    private IBluetoothHealth mService;
     BluetoothAdapter mAdapter;
 
     /**
      * Create a BluetoothHealth proxy object.
      */
-    /*package*/ BluetoothHealth(Context mContext, ServiceListener l) {
-        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+    /*package*/ BluetoothHealth(Context context, ServiceListener l) {
+        mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (b != null) {
-            mService = IBluetooth.Stub.asInterface(b);
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.HEALTH, this);
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
             }
-        } else {
-            Log.w(TAG, "Bluetooth Service not available!");
+        }
 
-            // Instead of throwing an exception which prevents people from going
-            // into Wireless settings in the emulator. Let it crash later when it is actually used.
-            mService = null;
+        if (!context.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth Health Service");
         }
     }
 
     /*package*/ void close() {
+        if (DBG) log("close()");
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
         mServiceListener = null;
     }
 
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothHealth.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.HEALTH, BluetoothHealth.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.HEALTH);
+            }
+        }
+    };
+
     private boolean isEnabled() {
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
old mode 100644
new mode 100755
index 1a9e011..bff966d
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -18,7 +18,10 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -41,7 +44,7 @@
  */
 public final class BluetoothInputDevice implements BluetoothProfile {
     private static final String TAG = "BluetoothInputDevice";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Intent used to broadcast the change in connection state of the Input
@@ -66,6 +69,22 @@
         "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
 
     /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PROTOCOL_MODE_CHANGED =
+        "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED";
+
+
+    /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_VIRTUAL_UNPLUG_STATUS =
+        "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS";
+
+
+    /**
      * Return codes for the connect and disconnect Bluez / Dbus calls.
      * @hide
      */
@@ -91,34 +110,159 @@
      */
     public static final int INPUT_OPERATION_SUCCESS = 5004;
 
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_REPORT_MODE = 0;
+
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_BOOT_MODE = 1;
+
+    /**
+     * @hide
+     */
+    public static final int PROTOCOL_UNSUPPORTED_MODE = 255;
+
+    /*  int reportType, int reportType, int bufferSize */
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_INPUT = 0;
+
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_OUTPUT = 1;
+
+    /**
+     * @hide
+     */
+    public static final byte REPORT_TYPE_FEATURE = 2;
+
+    /**
+     * @hide
+     */
+    public static final int VIRTUAL_UNPLUG_STATUS_SUCCESS = 0;
+
+    /**
+     * @hide
+     */
+    public static final int VIRTUAL_UNPLUG_STATUS_FAIL = 1;
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_PROTOCOL_MODE = "android.bluetooth.BluetoothInputDevice.extra.PROTOCOL_MODE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_TYPE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_TYPE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_ID = "android.bluetooth.BluetoothInputDevice.extra.REPORT_ID";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT_BUFFER_SIZE = "android.bluetooth.BluetoothInputDevice.extra.REPORT_BUFFER_SIZE";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_REPORT = "android.bluetooth.BluetoothInputDevice.extra.REPORT";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_VIRTUAL_UNPLUG_STATUS = "android.bluetooth.BluetoothInputDevice.extra.VIRTUAL_UNPLUG_STATUS";
+
+    private Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
-    private IBluetooth mService;
+    private IBluetoothInputDevice mService;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (DBG) Log.d(TAG,"Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (DBG) Log.d(TAG,"Binding service...");
+                                    if (!mContext.bindService(new Intent(IBluetoothInputDevice.class.getName()), mConnection, 0)) {
+                                        Log.e(TAG, "Could not bind to Bluetooth HID Service");
+                                    }
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG,"",re);
+                            }
+                        }
+                    }
+                }
+        };
 
     /**
      * Create a BluetoothInputDevice proxy object for interacting with the local
      * Bluetooth Service which handles the InputDevice profile
      *
      */
-    /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
-        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+    /*package*/ BluetoothInputDevice(Context context, ServiceListener l) {
+        mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (b != null) {
-            mService = IBluetooth.Stub.asInterface(b);
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
-            }
-        } else {
-            Log.w(TAG, "Bluetooth Service not available!");
 
-            // Instead of throwing an exception which prevents people from going
-            // into Wireless settings in the emulator. Let it crash later when it is actually used.
-            mService = null;
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()),
+                                 mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Service");
         }
     }
 
     /*package*/ void close() {
+        if (DBG) log("close()");
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG,"",e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+           }
+        }
         mServiceListener = null;
     }
 
@@ -144,10 +288,9 @@
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.connectInputDevice(device);
+                return mService.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
@@ -185,10 +328,9 @@
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
-            isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.disconnectInputDevice(device);
+                return mService.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
@@ -205,7 +347,7 @@
         if (DBG) log("getConnectedDevices()");
         if (mService != null && isEnabled()) {
             try {
-                return mService.getConnectedInputDevices();
+                return mService.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
@@ -222,7 +364,7 @@
         if (DBG) log("getDevicesMatchingStates()");
         if (mService != null && isEnabled()) {
             try {
-                return mService.getInputDevicesMatchingConnectionStates(states);
+                return mService.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
@@ -237,10 +379,9 @@
      */
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getInputDeviceConnectionState(device);
+                return mService.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
@@ -267,14 +408,13 @@
      */
     public boolean setPriority(BluetoothDevice device, int priority) {
         if (DBG) log("setPriority(" + device + ", " + priority + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             if (priority != BluetoothProfile.PRIORITY_OFF &&
                 priority != BluetoothProfile.PRIORITY_ON) {
               return false;
             }
             try {
-                return mService.setInputDevicePriority(device, priority);
+                return mService.setPriority(device, priority);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
@@ -299,10 +439,9 @@
      */
     public int getPriority(BluetoothDevice device) {
         if (DBG) log("getPriority(" + device + ")");
-        if (mService != null && isEnabled()
-            && isValidDevice(device)) {
+        if (mService != null && isEnabled() && isValidDevice(device)) {
             try {
-                return mService.getInputDevicePriority(device);
+                return mService.getPriority(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.PRIORITY_OFF;
@@ -312,6 +451,24 @@
         return BluetoothProfile.PRIORITY_OFF;
     }
 
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothInputDevice.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, BluetoothInputDevice.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_DEVICE);
+            }
+        }
+    };
+
     private boolean isEnabled() {
        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
        return false;
@@ -324,6 +481,158 @@
        return false;
     }
 
+
+    /**
+     * Initiate virtual unplug for a HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean virtualUnplug(BluetoothDevice device) {
+        if (DBG) log("virtualUnplug(" + device + ")");
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.virtualUnplug(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+
+    }
+
+    /**
+    * Send Get_Protocol_Mode command to the connected HID input device.
+    *
+    * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+    *
+    * @param device Remote Bluetooth Device
+    * @return false on immediate error,
+    *true otherwise
+    * @hide
+    */
+    public boolean getProtocolMode(BluetoothDevice device) {
+        if (DBG) log("getProtocolMode(" + device + ")");
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.getProtocolMode(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+            return false;
+    }
+
+    /**
+     * Send Set_Protocol_Mode command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean setProtocolMode(BluetoothDevice device, int protocolMode) {
+        if (DBG) log("setProtocolMode(" + device + ")");
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.setProtocolMode(device, protocolMode);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Get_Report command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param reportType Report type
+     * @param reportId Report ID
+     * @param bufferSize Report receiving buffer size
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) {
+        if (DBG) log("getReport(" + device + "), reportType=" + reportType + " reportId=" + reportId + "bufferSize=" + bufferSize);
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.getReport(device, reportType, reportId, bufferSize);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Set_Report command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param reportType Report type
+     * @param report Report receiving buffer size
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean setReport(BluetoothDevice device, byte reportType, String report) {
+        if (DBG) log("setReport(" + device + "), reportType=" + reportType + " report=" + report);
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.setReport(device, reportType, report);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Send Send_Data command to the connected HID input device.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+     *
+     * @param device Remote Bluetooth Device
+     * @param data Data to send
+     * @return false on immediate error,
+     *               true otherwise
+     * @hide
+     */
+    public boolean sendData(BluetoothDevice device, String report) {
+        if (DBG) log("sendData(" + device + "), report=" + report);
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.sendData(device, report);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
     private static void log(String msg) {
       Log.d(TAG, msg);
     }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 5d9d8be..cae7a73 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -18,7 +18,10 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -27,7 +30,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-
 /**
  * This class provides the APIs to control the Bluetooth Pan
  * Profile.
@@ -41,7 +43,7 @@
  */
 public final class BluetoothPan implements BluetoothProfile {
     private static final String TAG = "BluetoothPan";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Intent used to broadcast the change in connection state of the Pan
@@ -76,15 +78,18 @@
      */
     public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
 
+    public static final int PAN_ROLE_NONE = 0;
     /**
      * The local device is acting as a Network Access Point.
      */
     public static final int LOCAL_NAP_ROLE = 1;
+    public static final int REMOTE_NAP_ROLE = 1;
 
     /**
      * The local device is acting as a PAN User.
      */
     public static final int LOCAL_PANU_ROLE = 2;
+    public static final int REMOTE_PANU_ROLE = 2;
 
     /**
      * Return codes for the connect and disconnect Bluez / Dbus calls.
@@ -112,37 +117,77 @@
      */
     public static final int PAN_OPERATION_SUCCESS = 1004;
 
+    private Context mContext;
     private ServiceListener mServiceListener;
     private BluetoothAdapter mAdapter;
-    private IBluetooth mService;
+    private IBluetoothPan mPanService;
 
     /**
      * Create a BluetoothPan proxy object for interacting with the local
      * Bluetooth Service which handles the Pan profile
      *
      */
-    /*package*/ BluetoothPan(Context mContext, ServiceListener l) {
-        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+    /*package*/ BluetoothPan(Context context, ServiceListener l) {
+        mContext = context;
         mServiceListener = l;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (b != null) {
-            mService = IBluetooth.Stub.asInterface(b);
-            if (mServiceListener != null) {
-                mServiceListener.onServiceConnected(BluetoothProfile.PAN, this);
-            }
-        } else {
-            Log.w(TAG, "Bluetooth Service not available!");
-
-            // Instead of throwing an exception which prevents people from going
-            // into Wireless settings in the emulator. Let it crash later when it is actually used.
-            mService = null;
+        try {
+            mAdapter.getBluetoothManager().registerStateChangeCallback(mStateChangeCallback);
+        } catch (RemoteException re) {
+            Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
         }
+        Log.d(TAG, "BluetoothPan() call bindService");
+        if (!context.bindService(new Intent(IBluetoothPan.class.getName()),
+                                 mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Service");
+        }
+        Log.d(TAG, "BluetoothPan(), bindService called");
     }
 
     /*package*/ void close() {
+        if (DBG) log("close()");
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+            mConnection = null;
+        }
         mServiceListener = null;
+        try {
+            mAdapter.getBluetoothManager().unregisterStateChangeCallback(mStateChangeCallback);
+        } catch (RemoteException re) {
+            Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
+        }
     }
 
+    protected void finalize() {
+        close();
+    }
+
+    private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
+
+        @Override
+        public void onBluetoothStateChange(boolean on) throws RemoteException {
+            //Handle enable request to bind again.
+            if (on) {
+                Log.d(TAG, "onBluetoothStateChange(on) call bindService");
+                if (!mContext.bindService(new Intent(IBluetoothPan.class.getName()),
+                                     mConnection, 0)) {
+                    Log.e(TAG, "Could not bind to Bluetooth HID Service");
+                }
+                Log.d(TAG, "BluetoothPan(), bindService called");
+            } else {
+                if (DBG) Log.d(TAG,"Unbinding service...");
+                synchronized (mConnection) {
+                    try {
+                        mPanService = null;
+                        mContext.unbindService(mConnection);
+                    } catch (Exception re) {
+                        Log.e(TAG,"",re);
+                    }
+                }
+            }
+        }
+    };
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
@@ -163,16 +208,16 @@
      */
     public boolean connect(BluetoothDevice device) {
         if (DBG) log("connect(" + device + ")");
-        if (mService != null && isEnabled() &&
+        if (mPanService != null && isEnabled() &&
             isValidDevice(device)) {
             try {
-                return mService.connectPanDevice(device);
+                return mPanService.connect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -204,16 +249,16 @@
      */
     public boolean disconnect(BluetoothDevice device) {
         if (DBG) log("disconnect(" + device + ")");
-        if (mService != null && isEnabled() &&
+        if (mPanService != null && isEnabled() &&
             isValidDevice(device)) {
             try {
-                return mService.disconnectPanDevice(device);
+                return mPanService.disconnect(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return false;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
         return false;
     }
 
@@ -222,15 +267,15 @@
      */
     public List<BluetoothDevice> getConnectedDevices() {
         if (DBG) log("getConnectedDevices()");
-        if (mService != null && isEnabled()) {
+        if (mPanService != null && isEnabled()) {
             try {
-                return mService.getConnectedPanDevices();
+                return mPanService.getConnectedDevices();
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -239,15 +284,15 @@
      */
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
         if (DBG) log("getDevicesMatchingStates()");
-        if (mService != null && isEnabled()) {
+        if (mPanService != null && isEnabled()) {
             try {
-                return mService.getPanDevicesMatchingConnectionStates(states);
+                return mPanService.getDevicesMatchingConnectionStates(states);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return new ArrayList<BluetoothDevice>();
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
         return new ArrayList<BluetoothDevice>();
     }
 
@@ -256,23 +301,23 @@
      */
     public int getConnectionState(BluetoothDevice device) {
         if (DBG) log("getState(" + device + ")");
-        if (mService != null && isEnabled()
+        if (mPanService != null && isEnabled()
             && isValidDevice(device)) {
             try {
-                return mService.getPanDeviceConnectionState(device);
+                return mPanService.getConnectionState(device);
             } catch (RemoteException e) {
                 Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
                 return BluetoothProfile.STATE_DISCONNECTED;
             }
         }
-        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        if (mPanService == null) Log.w(TAG, "Proxy not attached to service");
         return BluetoothProfile.STATE_DISCONNECTED;
     }
 
     public void setBluetoothTethering(boolean value) {
         if (DBG) log("setBluetoothTethering(" + value + ")");
         try {
-            mService.setBluetoothTethering(value);
+            mPanService.setBluetoothTethering(value);
         } catch (RemoteException e) {
             Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
         }
@@ -281,13 +326,32 @@
     public boolean isTetheringOn() {
         if (DBG) log("isTetheringOn()");
         try {
-            return mService.isTetheringOn();
+            return mPanService.isTetheringOn();
         } catch (RemoteException e) {
             Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
-            return false;
         }
+        return false;
     }
 
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
+            mPanService = IBluetoothPan.Stub.asInterface(service);
+
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.PAN,
+                                                    BluetoothPan.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "BluetoothPAN Proxy object disconnected");
+            mPanService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.PAN);
+            }
+        }
+    };
+
     private boolean isEnabled() {
        if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
        return false;
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
deleted file mode 100644
index b0c0a0b..0000000
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.bluetooth;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-/**
- * This state machine is used to serialize the connections
- * to a particular profile. Currently, we only allow one device
- * to be connected to a particular profile.
- * States:
- *      {@link StableState} : No pending commands. Send the
- *      command to the appropriate remote device specific state machine.
- *
- *      {@link PendingCommandState} : A profile connection / disconnection
- *      command is being executed. This will result in a profile state
- *      change. Defer all commands.
- * @hide
- */
-
-public class BluetoothProfileState extends StateMachine {
-    private static final boolean DBG = true;
-    private static final String TAG = "BluetoothProfileState";
-
-    public static final int HFP = 0;
-    public static final int A2DP = 1;
-    public static final int HID = 2;
-
-    static final int TRANSITION_TO_STABLE = 100;
-
-    private int mProfile;
-    private BluetoothDevice mPendingDevice;
-    private PendingCommandState mPendingCommandState = new PendingCommandState();
-    private StableState mStableState = new StableState();
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            if (device == null) {
-                return;
-            }
-            if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                if (mProfile == HFP && (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED)) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                if (mProfile == A2DP && (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED)) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                if (mProfile == HID && (newState == BluetoothProfile.STATE_CONNECTED ||
-                    newState == BluetoothProfile.STATE_DISCONNECTED)) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
-                if (device.equals(mPendingDevice)) {
-                    sendMessage(TRANSITION_TO_STABLE);
-                }
-            }
-        }
-    };
-
-    public BluetoothProfileState(Context context, int profile) {
-        super("BluetoothProfileState:" + profile);
-        mProfile = profile;
-        addState(mStableState);
-        addState(mPendingCommandState);
-        setInitialState(mStableState);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
-        context.registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    private class StableState extends State {
-        @Override
-        public void enter() {
-            log("Entering Stable State");
-            mPendingDevice = null;
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what != TRANSITION_TO_STABLE) {
-                transitionTo(mPendingCommandState);
-            }
-            return true;
-        }
-    }
-
-    private class PendingCommandState extends State {
-        @Override
-        public void enter() {
-            log("Entering PendingCommandState State");
-            dispatchMessage(getCurrentMessage());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what == TRANSITION_TO_STABLE) {
-                transitionTo(mStableState);
-            } else {
-                dispatchMessage(msg);
-            }
-            return true;
-        }
-
-        private void dispatchMessage(Message msg) {
-            BluetoothDeviceProfileState deviceProfileMgr =
-              (BluetoothDeviceProfileState)msg.obj;
-            int cmd = msg.arg1;
-            if (mPendingDevice == null || mPendingDevice.equals(deviceProfileMgr.getDevice())) {
-                mPendingDevice = deviceProfileMgr.getDevice();
-                deviceProfileMgr.sendMessage(cmd);
-            } else {
-                Message deferMsg = new Message();
-                deferMsg.arg1 = cmd;
-                deferMsg.obj = deviceProfileMgr;
-                deferMessage(deferMsg);
-            }
-        }
-    }
-
-    private void log(String message) {
-        if (DBG) {
-            Log.i(TAG, "Message:" + message);
-        }
-    }
-}
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 4021f7b..96be8a2 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -17,6 +17,8 @@
 package android.bluetooth;
 
 import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelUuid;
 
 import java.io.Closeable;
 import java.io.IOException;
@@ -86,6 +88,22 @@
     }
 
     /**
+     * Construct a socket for incoming connections.
+     * @param type    type of socket
+     * @param auth    require the remote device to be authenticated
+     * @param encrypt require the connection to be encrypted
+     * @param uuid    uuid
+     * @throws IOException On error, for example Bluetooth not available, or
+     *                     insufficient privileges
+     */
+    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, ParcelUuid uuid)
+            throws IOException {
+        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, -1, uuid);
+        mChannel = mSocket.getPort();
+    }
+
+
+    /**
      * Block until a connection is established.
      * <p>Returns a connected {@link BluetoothSocket} on successful connection.
      * <p>Once this call returns, it can be called again to accept subsequent
@@ -133,7 +151,9 @@
         mHandler = handler;
         mMessage = message;
     }
-
+    /*package*/ void setServiceName(String ServiceName) {
+        mSocket.setServiceName(ServiceName);
+    }
     /**
      * Returns the channel on which this socket is bound.
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 20e8515..1bc640f 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -1,32 +1,27 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Copyright (C) 2012 Google Inc.
  */
 
 package android.bluetooth;
 
-import android.bluetooth.IBluetoothCallback;
+import android.os.IBinder;
 import android.os.ParcelUuid;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
+import java.util.List;
+import android.net.LocalSocket;
+import java.nio.ByteOrder;
+import java.nio.ByteBuffer;
 /**
  * A connected or connecting Bluetooth socket.
  *
@@ -89,31 +84,40 @@
     /*package*/ static final int EBADFD = 77;
     /*package*/ static final int EADDRINUSE = 98;
 
+    /*package*/ static final int SEC_FLAG_ENCRYPT = 1;
+    /*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
+
     private final int mType;  /* one of TYPE_RFCOMM etc */
-    private final BluetoothDevice mDevice;    /* remote device */
-    private final String mAddress;    /* remote address */
+    private BluetoothDevice mDevice;    /* remote device */
+    private String mAddress;    /* remote address */
     private final boolean mAuth;
     private final boolean mEncrypt;
     private final BluetoothInputStream mInputStream;
     private final BluetoothOutputStream mOutputStream;
-    private final SdpHelper mSdp;
-
+    private final ParcelUuid mUuid;
+    private ParcelFileDescriptor mPfd;
+    private LocalSocket mSocket;
+    private InputStream mSocketIS;
+    private OutputStream mSocketOS;
     private int mPort;  /* RFCOMM channel or L2CAP psm */
+    private int mFd;
+    private String mServiceName;
+    private static int PROXY_CONNECTION_TIMEOUT = 5000;
+
+    private static int SOCK_SIGNAL_SIZE = 16;
 
     private enum SocketState {
         INIT,
         CONNECTED,
-        CLOSED
+        LISTENING,
+        CLOSED,
     }
 
     /** prevents all native calls after destroyNative() */
-    private SocketState mSocketState;
+    private volatile SocketState mSocketState;
 
     /** protects mSocketState */
-    private final ReentrantReadWriteLock mLock;
-
-    /** used by native code only */
-    private int mSocketData;
+    //private final ReentrantReadWriteLock mLock;
 
     /**
      * Construct a BluetoothSocket.
@@ -134,33 +138,52 @@
                 throw new IOException("Invalid RFCOMM channel: " + port);
             }
         }
-        if (uuid == null) {
-            mPort = port;
-            mSdp = null;
-        } else {
-            mSdp = new SdpHelper(device, uuid);
-            mPort = -1;
-        }
+        mUuid = uuid;
         mType = type;
         mAuth = auth;
         mEncrypt = encrypt;
         mDevice = device;
+        mPort = port;
+        mFd = fd;
+
+        mSocketState = SocketState.INIT;
+
         if (device == null) {
-            mAddress = null;
+            // Server socket
+            mAddress = BluetoothAdapter.getDefaultAdapter().getAddress();
         } else {
+            // Remote socket
             mAddress = device.getAddress();
         }
-        if (fd == -1) {
-            initSocketNative();
-        } else {
-            initSocketFromFdNative(fd);
-        }
         mInputStream = new BluetoothInputStream(this);
         mOutputStream = new BluetoothOutputStream(this);
-        mSocketState = SocketState.INIT;
-        mLock = new ReentrantReadWriteLock();
     }
-
+    private BluetoothSocket(BluetoothSocket s) {
+        mUuid = s.mUuid;
+        mType = s.mType;
+        mAuth = s.mAuth;
+        mEncrypt = s.mEncrypt;
+        mPort = s.mPort;
+        mInputStream = new BluetoothInputStream(this);
+        mOutputStream = new BluetoothOutputStream(this);
+        mServiceName = s.mServiceName;
+    }
+    private BluetoothSocket acceptSocket(String RemoteAddr) throws IOException {
+        BluetoothSocket as = new BluetoothSocket(this);
+        as.mSocketState = SocketState.CONNECTED;
+        FileDescriptor[] fds = mSocket.getAncillaryFileDescriptors();
+        Log.d(TAG, "socket fd passed by stack  fds: " + fds);
+        if(fds == null || fds.length != 1) {
+            Log.e(TAG, "socket fd passed from stack failed, fds: " + fds);
+            throw new IOException("bt socket acept failed");
+        }
+        as.mSocket = new LocalSocket(fds[0]);
+        as.mSocketIS = as.mSocket.getInputStream();
+        as.mSocketOS = as.mSocket.getOutputStream();
+        as.mAddress = RemoteAddr;
+        as.mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(RemoteAddr);
+        return as;
+    }
     /**
      * Construct a BluetoothSocket from address. Used by native code.
      * @param type    type of socket
@@ -186,69 +209,13 @@
             super.finalize();
         }
     }
-
-    /**
-     * Attempt to connect to a remote device.
-     * <p>This method will block until a connection is made or the connection
-     * fails. If this method returns without an exception then this socket
-     * is now connected.
-     * <p>Creating new connections to
-     * remote Bluetooth devices should not be attempted while device discovery
-     * is in progress. Device discovery is a heavyweight procedure on the
-     * Bluetooth adapter and will significantly slow a device connection.
-     * Use {@link BluetoothAdapter#cancelDiscovery()} to cancel an ongoing
-     * discovery. Discovery is not managed by the Activity,
-     * but is run as a system service, so an application should always call
-     * {@link BluetoothAdapter#cancelDiscovery()} even if it
-     * did not directly request a discovery, just to be sure.
-     * <p>{@link #close} can be used to abort this call from another thread.
-     * @throws IOException on error, for example connection failure
-     */
-    public void connect() throws IOException {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-
-            if (mSdp != null) {
-                mPort = mSdp.doSdp();  // blocks
-            }
-
-            connectNative();  // blocks
-            mSocketState = SocketState.CONNECTED;
-        } finally {
-            mLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Immediately close this socket, and release all associated resources.
-     * <p>Causes blocked calls on this socket in other threads to immediately
-     * throw an IOException.
-     */
-    public void close() throws IOException {
-        // abort blocking operations on the socket
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) return;
-            if (mSdp != null) {
-                mSdp.cancel();
-            }
-            abortNative();
-        } finally {
-            mLock.readLock().unlock();
-        }
-
-        // all native calls are guaranteed to immediately return after
-        // abortNative(), so this lock should immediately acquire
-        mLock.writeLock().lock();
-        try {
-            if (mSocketState != SocketState.CLOSED) {
-                mSocketState = SocketState.CLOSED;
-                destroyNative();
-            }
-        } finally {
-            mLock.writeLock().unlock();
-        }
+    private int getSecurityFlags() {
+        int flags = 0;
+        if(mAuth)
+            flags |= SEC_FLAG_AUTH;
+        if(mEncrypt)
+            flags |= SEC_FLAG_ENCRYPT;
+        return flags;
     }
 
     /**
@@ -288,7 +255,64 @@
      *         false if not connected
      */
     public boolean isConnected() {
-        return (mSocketState == SocketState.CONNECTED);
+        return mSocketState == SocketState.CONNECTED;
+    }
+
+    /*package*/ void setServiceName(String name) {
+        mServiceName = name;
+    }
+
+    /**
+     * Attempt to connect to a remote device.
+     * <p>This method will block until a connection is made or the connection
+     * fails. If this method returns without an exception then this socket
+     * is now connected.
+     * <p>Creating new connections to
+     * remote Bluetooth devices should not be attempted while device discovery
+     * is in progress. Device discovery is a heavyweight procedure on the
+     * Bluetooth adapter and will significantly slow a device connection.
+     * Use {@link BluetoothAdapter#cancelDiscovery()} to cancel an ongoing
+     * discovery. Discovery is not managed by the Activity,
+     * but is run as a system service, so an application should always call
+     * {@link BluetoothAdapter#cancelDiscovery()} even if it
+     * did not directly request a discovery, just to be sure.
+     * <p>{@link #close} can be used to abort this call from another thread.
+     * @throws IOException on error, for example connection failure
+     */
+    public void connect() throws IOException {
+        if (mDevice == null) throw new IOException("Connect is called on null device");
+
+        try {
+            // TODO(BT) derive flag from auth and encrypt
+            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
+            IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+            if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
+            mPfd = bluetoothProxy.connectSocket(mDevice, mType,
+                    mUuid, mPort, getSecurityFlags());
+            synchronized(this)
+            {
+                Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
+                if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
+                if (mPfd == null) throw new IOException("bt socket connect failed");
+                FileDescriptor fd = mPfd.getFileDescriptor();
+                mSocket = new LocalSocket(fd);
+                mSocketIS = mSocket.getInputStream();
+                mSocketOS = mSocket.getOutputStream();
+            }
+            int channel = readInt(mSocketIS);
+            if (channel <= 0)
+                throw new IOException("bt socket connect failed");
+            mPort = channel;
+            waitSocketSignal(mSocketIS);
+            synchronized(this)
+            {
+                if (mSocketState == SocketState.CLOSED)
+                    throw new IOException("bt socket closed");
+                mSocketState = SocketState.CONNECTED;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, Log.getStackTraceString(new Throwable()));
+        }
     }
 
     /**
@@ -296,129 +320,170 @@
      * so that BluetoothAdapter can check the error code for EADDRINUSE
      */
     /*package*/ int bindListen() {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) return EBADFD;
-            return bindListenNative();
-        } finally {
-            mLock.readLock().unlock();
+        int ret;
+        if (mSocketState == SocketState.CLOSED) return EBADFD;
+        IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+        if (bluetoothProxy == null) {
+            Log.e(TAG, "bindListen fail, reason: bluetooth is off");
+            return -1;
         }
+        try {
+            mPfd = bluetoothProxy.createSocketChannel(mType, mServiceName,
+                    mUuid, mPort, getSecurityFlags());
+        } catch (RemoteException e) {
+            Log.e(TAG, Log.getStackTraceString(new Throwable()));
+            // TODO(BT) right error code?
+            return -1;
+        }
+
+        // read out port number
+        try {
+            synchronized(this) {
+                Log.d(TAG, "bindListen(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
+                if(mSocketState != SocketState.INIT) return EBADFD;
+                if(mPfd == null) return -1;
+                FileDescriptor fd = mPfd.getFileDescriptor();
+                Log.d(TAG, "bindListen(), new LocalSocket ");
+                mSocket = new LocalSocket(fd);
+                Log.d(TAG, "bindListen(), new LocalSocket.getInputStream() ");
+                mSocketIS = mSocket.getInputStream();
+                mSocketOS = mSocket.getOutputStream();
+            }
+            Log.d(TAG, "bindListen(), readInt mSocketIS: " + mSocketIS);
+            int channel = readInt(mSocketIS);
+            synchronized(this) {
+                if(mSocketState == SocketState.INIT)
+                    mSocketState = SocketState.LISTENING;
+            }
+            Log.d(TAG, "channel: " + channel);
+            if (mPort == -1) {
+                mPort = channel;
+            } // else ASSERT(mPort == channel)
+            ret = 0;
+        } catch (IOException e) {
+            Log.e(TAG, "bindListen, fail to get port number, exception: " + e);
+            return -1;
+        }
+        return ret;
     }
 
     /*package*/ BluetoothSocket accept(int timeout) throws IOException {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-
-            BluetoothSocket acceptedSocket = acceptNative(timeout);
-            mSocketState = SocketState.CONNECTED;
-            return acceptedSocket;
-        } finally {
-            mLock.readLock().unlock();
+        BluetoothSocket acceptedSocket;
+        if (mSocketState != SocketState.LISTENING) throw new IOException("bt socket is not in listen state");
+        // TODO(BT) wait on an incoming connection
+        String RemoteAddr = waitSocketSignal(mSocketIS);
+        synchronized(this)
+        {
+            if (mSocketState != SocketState.LISTENING)
+                throw new IOException("bt socket is not in listen state");
+            acceptedSocket = acceptSocket(RemoteAddr);
+            //quick drop the reference of the file handle
         }
+        // TODO(BT) rfcomm socket only supports one connection, return this?
+        // return this;
+        return acceptedSocket;
     }
 
     /*package*/ int available() throws IOException {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-            return availableNative();
-        } finally {
-            mLock.readLock().unlock();
-        }
+        Log.d(TAG, "available: " + mSocketIS);
+        return mSocketIS.available();
     }
 
     /*package*/ int read(byte[] b, int offset, int length) throws IOException {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-            return readNative(b, offset, length);
-        } finally {
-            mLock.readLock().unlock();
-        }
+
+            Log.d(TAG, "read in:  " + mSocketIS + " len: " + length);
+            int ret = mSocketIS.read(b, offset, length);
+            if(ret < 0)
+                throw new IOException("bt socket closed, read return: " + ret);
+            Log.d(TAG, "read out:  " + mSocketIS + " ret: " + ret);
+            return ret;
     }
 
     /*package*/ int write(byte[] b, int offset, int length) throws IOException {
-        mLock.readLock().lock();
-        try {
-            if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
-            return writeNative(b, offset, length);
-        } finally {
-            mLock.readLock().unlock();
-        }
+
+            Log.d(TAG, "write: " + mSocketOS + " length: " + length);
+            mSocketOS.write(b, offset, length);
+            // There is no good way to confirm since the entire process is asynchronous anyway
+            Log.d(TAG, "write out: " + mSocketOS + " length: " + length);
+            return length;
     }
 
-    private native void initSocketNative() throws IOException;
-    private native void initSocketFromFdNative(int fd) throws IOException;
-    private native void connectNative() throws IOException;
-    private native int bindListenNative();
-    private native BluetoothSocket acceptNative(int timeout) throws IOException;
-    private native int availableNative() throws IOException;
-    private native int readNative(byte[] b, int offset, int length) throws IOException;
-    private native int writeNative(byte[] b, int offset, int length) throws IOException;
-    private native void abortNative() throws IOException;
-    private native void destroyNative() throws IOException;
-    /**
-     * Throws an IOException for given posix errno. Done natively so we can
-     * use strerr to convert to string error.
-     */
-    /*package*/ native void throwErrnoNative(int errno) throws IOException;
-
-    /**
-     * Helper to perform blocking SDP lookup.
-     */
-    private static class SdpHelper extends IBluetoothCallback.Stub {
-        private final IBluetooth service;
-        private final ParcelUuid uuid;
-        private final BluetoothDevice device;
-        private int channel;
-        private boolean canceled;
-        public SdpHelper(BluetoothDevice device, ParcelUuid uuid) {
-            service = BluetoothDevice.getService();
-            this.device = device;
-            this.uuid = uuid;
-            canceled = false;
+    @Override
+    public void close() throws IOException {
+        Log.d(TAG, "close() in, this: " + this + ", channel: " + mPort + ", state: " + mSocketState);
+        if(mSocketState == SocketState.CLOSED)
+            return;
+        else
+        {
+            synchronized(this)
+            {
+                 if(mSocketState == SocketState.CLOSED)
+                    return;
+                 mSocketState = SocketState.CLOSED;
+                 Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS +
+                        ", mSocketOS: " + mSocketOS + "mSocket: " + mSocket);
+                 if(mSocket != null) {
+                    Log.d(TAG, "Closing mSocket: " + mSocket);
+                    mSocket.shutdownInput();
+                    mSocket.shutdownOutput();
+                    mSocket.close();
+                    mSocket = null;
+                }
+                if(mPfd != null)
+                    mPfd.detachFd();
+           }
         }
-        /**
-         * Returns the RFCOMM channel for the UUID, or throws IOException
-         * on failure.
-         */
-        public synchronized int doSdp() throws IOException {
-            if (canceled) throw new IOException("Service discovery canceled");
-            channel = -1;
+        // TODO(BT) unbind proxy,
+    }
 
-            boolean inProgress = false;
-            try {
-                inProgress = service.fetchRemoteUuids(device.getAddress(), uuid, this);
-            } catch (RemoteException e) {Log.e(TAG, "", e);}
+    /*package */ void removeChannel() {
+    }
 
-            if (!inProgress) throw new IOException("Unable to start Service Discovery");
-
-            try {
-                /* 12 second timeout as a precaution - onRfcommChannelFound
-                 * should always occur before the timeout */
-                wait(12000);   // block
-
-            } catch (InterruptedException e) {}
-
-            if (canceled) throw new IOException("Service discovery canceled");
-            if (channel < 1) throw new IOException("Service discovery failed");
-
-            return channel;
+    /*package */ int getPort() {
+        return mPort;
+    }
+    private String convertAddr(final byte[] addr)  {
+        return String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+                addr[0] , addr[1], addr[2], addr[3] , addr[4], addr[5]);
+    }
+    private String waitSocketSignal(InputStream is) throws IOException {
+        byte [] sig = new byte[SOCK_SIGNAL_SIZE];
+        int ret = readAll(is, sig);
+        Log.d(TAG, "waitSocketSignal read 16 bytes signal ret: " + ret);
+        ByteBuffer bb = ByteBuffer.wrap(sig);
+        bb.order(ByteOrder.nativeOrder());
+        int size = bb.getShort();
+        byte [] addr = new byte[6];
+        bb.get(addr);
+        int channel = bb.getInt();
+        int status = bb.getInt();
+        String RemoteAddr = convertAddr(addr);
+        Log.d(TAG, "waitSocketSignal: sig size: " + size + ", remote addr: "
+                + RemoteAddr + ", channel: " + channel + ", status: " + status);
+        if(status != 0)
+            throw new IOException("Connection failure, status: " + status);
+        return RemoteAddr;
+    }
+    private int readAll(InputStream is, byte[] b) throws IOException {
+        int left = b.length;
+        while(left > 0) {
+            int ret = is.read(b, b.length - left, left);
+            if(ret <= 0)
+                 throw new IOException("read failed, socket might closed, read ret: " + ret);
+            left -= ret;
+            if(left != 0)
+                Log.w(TAG, "readAll() looping, read partial size: " + (b.length - left) +
+                            ", expect size: " + b.length);
         }
-        /** Object cannot be re-used after calling cancel() */
-        public synchronized void cancel() {
-            if (!canceled) {
-                canceled = true;
-                channel = -1;
-                notifyAll();  // unblock
-            }
-        }
-        public synchronized void onRfcommChannelFound(int channel) {
-            if (!canceled) {
-                this.channel = channel;
-                notifyAll();  // unblock
-            }
-        }
+        return b.length;
+    }
+
+    private int readInt(InputStream is) throws IOException {
+        byte[] ibytes = new byte[4];
+        int ret = readAll(is, ibytes);
+        Log.d(TAG, "inputStream.read ret: " + ret);
+        ByteBuffer bb = ByteBuffer.wrap(ibytes);
+        bb.order(ByteOrder.nativeOrder());
+        return bb.getInt();
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index 83d1bda..b2b5d81 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -16,6 +16,9 @@
 
 package android.bluetooth;
 
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.os.INetworkManagementService;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.DhcpInfoInternal;
@@ -28,6 +31,11 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
+import java.net.InterfaceAddress;
+import android.net.LinkAddress;
+import android.net.RouteInfo;
+import java.net.Inet4Address;
+import android.os.SystemProperties;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -54,9 +62,8 @@
     private NetworkInfo mNetworkInfo;
 
     private BluetoothPan mBluetoothPan;
-    private BluetoothDevice mDevice;
     private static String mIface;
-
+    private Thread mDhcpThread;
     /* For sending events to connectivity service handler */
     private Handler mCsHandler;
     private Context mContext;
@@ -92,8 +99,10 @@
      * Begin monitoring connectivity
      */
     public void startMonitoring(Context context, Handler target) {
+        Log.d(TAG, "startMonitoring: target: " + target);
         mContext = context;
         mCsHandler = target;
+        Log.d(TAG, "startMonitoring: mCsHandler: " + mCsHandler);
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
             adapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.PAN);
@@ -259,38 +268,91 @@
         return "net.tcp.buffersize.wifi";
     }
 
+    private static short countPrefixLength(byte [] mask) {
+        short count = 0;
+        for (byte b : mask) {
+            for (int i = 0; i < 8; ++i) {
+                if ((b & (1 << i)) != 0) {
+                    ++count;
+                }
+            }
+        }
+        return count;
+    }
 
-    public synchronized void startReverseTether(String iface, BluetoothDevice device) {
+
+    private boolean readLinkProperty(String iface) {
+        String DhcpPrefix = "dhcp." + iface + ".";
+        String ip = SystemProperties.get(DhcpPrefix + "ipaddress");
+        String dns1 = SystemProperties.get(DhcpPrefix + "dns1");
+        String dns2 = SystemProperties.get(DhcpPrefix + "dns2");
+        String gateway = SystemProperties.get(DhcpPrefix + "gateway");
+        String mask = SystemProperties.get(DhcpPrefix + "mask");
+        if(ip.isEmpty() || gateway.isEmpty()) {
+            Log.e(TAG, "readLinkProperty, ip: " +  ip + ", gateway: " + gateway + ", can not be empty");
+            return false;
+        }
+        int PrefixLen = countPrefixLength(NetworkUtils.numericToInetAddress(mask).getAddress());
+        mLinkProperties.addLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(ip), PrefixLen));
+        RouteInfo ri = new RouteInfo(NetworkUtils.numericToInetAddress(gateway));
+        mLinkProperties.addRoute(ri);
+        if(!dns1.isEmpty())
+            mLinkProperties.addDns(NetworkUtils.numericToInetAddress(dns1));
+        if(!dns2.isEmpty())
+            mLinkProperties.addDns(NetworkUtils.numericToInetAddress(dns2));
+        mLinkProperties.setInterfaceName(iface);
+        return true;
+    }
+    public synchronized void startReverseTether(String iface) {
         mIface = iface;
-        mDevice = device;
-        Thread dhcpThread = new Thread(new Runnable() {
+        Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+         mDhcpThread = new Thread(new Runnable() {
             public void run() {
                 //TODO(): Add callbacks for failure and success case.
                 //Currently this thread runs independently.
-                DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
-                if (!NetworkUtils.runDhcp(mIface, dhcpInfoInternal)) {
-                    Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
-                    return;
+                Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+                String DhcpResultName = "dhcp." + mIface + ".result";;
+                String result = "";
+                Log.d(TAG, "waiting for change of sys prop dhcp result: " + DhcpResultName);
+                for(int i = 0; i < 30*5; i++) {
+                    try { Thread.sleep(200); } catch (InterruptedException ie) { return;}
+                    result = SystemProperties.get(DhcpResultName);
+                    Log.d(TAG, "read " + DhcpResultName + ": " + result);
+                    if(result.equals("failed")) {
+                        Log.e(TAG, "startReverseTether, failed to start dhcp service");
+                        return;
+                    }
+                    if(result.equals("ok")) {
+                        Log.d(TAG, "startReverseTether, dhcp resut: " + result);
+                        if(readLinkProperty(mIface)) {
+
+                            mNetworkInfo.setIsAvailable(true);
+                            mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
+
+                            Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
+                            if(mCsHandler != null) {
+                                Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
+                                msg.sendToTarget();
+
+                                msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+                                msg.sendToTarget();
+                            }
+                        }
+                        return;
+                    }
                 }
-                mLinkProperties = dhcpInfoInternal.makeLinkProperties();
-                mLinkProperties.setInterfaceName(mIface);
-
-                mNetworkInfo.setIsAvailable(true);
-                mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
-
-                Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
-                msg.sendToTarget();
-
-                msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
-                msg.sendToTarget();
+                Log.d(TAG, "startReverseTether, dhcp failed, resut: " + result);
             }
         });
-        dhcpThread.start();
+        mDhcpThread.start();
     }
 
-    public synchronized void stopReverseTether(String iface) {
-        NetworkUtils.stopDhcp(iface);
-
+    public synchronized void stopReverseTether() {
+        //NetworkUtils.stopDhcp(iface);
+        if(mDhcpThread != null && mDhcpThread.isAlive()) {
+            mDhcpThread.interrupt();
+            try { mDhcpThread.join(); } catch (InterruptedException ie) { return; }
+        }
         mLinkProperties.clear();
         mNetworkInfo.setIsAvailable(false);
         mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
diff --git a/core/java/android/bluetooth/HeadsetBase.java b/core/java/android/bluetooth/HeadsetBase.java
deleted file mode 100644
index 9ef2eb5..0000000
--- a/core/java/android/bluetooth/HeadsetBase.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.bluetooth;
-
-import android.os.Handler;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.util.Log;
-
-/**
- * The Android Bluetooth API is not finalized, and *will* change. Use at your
- * own risk.
- *
- * The base RFCOMM (service) connection for a headset or handsfree device.
- *
- * In the future this class will be removed.
- *
- * @hide
- */
-public final class HeadsetBase {
-    private static final String TAG = "Bluetooth HeadsetBase";
-    private static final boolean DBG = false;
-
-    public static final int RFCOMM_DISCONNECTED = 1;
-
-    public static final int DIRECTION_INCOMING = 1;
-    public static final int DIRECTION_OUTGOING = 2;
-
-    private static int sAtInputCount = 0;  /* TODO: Consider not using a static variable */
-
-    private final BluetoothAdapter mAdapter;
-    private final BluetoothDevice mRemoteDevice;
-    private final String mAddress;  // for native code
-    private final int mRfcommChannel;
-    private int mNativeData;
-    private Thread mEventThread;
-    private volatile boolean mEventThreadInterrupted;
-    private Handler mEventThreadHandler;
-    private int mTimeoutRemainingMs;
-    private final int mDirection;
-    private final long mConnectTimestamp;
-
-    protected AtParser mAtParser;
-
-    private WakeLock mWakeLock;  // held while processing an AT command
-
-    private native static void classInitNative();
-    static {
-        classInitNative();
-    }
-
-    protected void finalize() throws Throwable {
-        try {
-            cleanupNativeDataNative();
-            releaseWakeLock();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    private native void cleanupNativeDataNative();
-
-    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
-                       BluetoothDevice device, int rfcommChannel) {
-        mDirection = DIRECTION_OUTGOING;
-        mConnectTimestamp = System.currentTimeMillis();
-        mAdapter = adapter;
-        mRemoteDevice = device;
-        mAddress = device.getAddress();
-        mRfcommChannel = rfcommChannel;
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "HeadsetBase");
-        mWakeLock.setReferenceCounted(false);
-        initializeAtParser();
-        // Must be called after this.mAddress is set.
-        initializeNativeDataNative(-1);
-    }
-
-    /* Create from an existing rfcomm connection */
-    public HeadsetBase(PowerManager pm, BluetoothAdapter adapter,
-                       BluetoothDevice device,
-                       int socketFd, int rfcommChannel, Handler handler) {
-        mDirection = DIRECTION_INCOMING;
-        mConnectTimestamp = System.currentTimeMillis();
-        mAdapter = adapter;
-        mRemoteDevice = device;
-        mAddress = device.getAddress();
-        mRfcommChannel = rfcommChannel;
-        mEventThreadHandler = handler;
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "HeadsetBase");
-        mWakeLock.setReferenceCounted(false);
-        initializeAtParser();
-        // Must be called after this.mAddress is set.
-        initializeNativeDataNative(socketFd);
-    }
-
-    private native void initializeNativeDataNative(int socketFd);
-
-    /* Process an incoming AT command line
-     */
-    protected void handleInput(String input) {
-        acquireWakeLock();
-        long timestamp;
-
-        synchronized(HeadsetBase.class) {
-            if (sAtInputCount == Integer.MAX_VALUE) {
-                sAtInputCount = 0;
-            } else {
-                sAtInputCount++;
-            }
-        }
-
-        if (DBG) timestamp = System.currentTimeMillis();
-        AtCommandResult result = mAtParser.process(input);
-        if (DBG) Log.d(TAG, "Processing " + input + " took " +
-                       (System.currentTimeMillis() - timestamp) + " ms");
-
-        if (result.getResultCode() == AtCommandResult.ERROR) {
-            Log.i(TAG, "Error processing <" + input + ">");
-        }
-
-        sendURC(result.toString());
-
-        releaseWakeLock();
-    }
-
-    /**
-     * Register AT commands that are common to all Headset / Handsets. This
-     * function is called by the HeadsetBase constructor.
-     */
-    protected void initializeAtParser() {
-        mAtParser = new AtParser();
-
-        //TODO(): Get rid of this as there are no parsers registered. But because of dependencies
-        // it needs to be done as part of refactoring HeadsetBase and BluetoothHandsfree
-    }
-
-    public AtParser getAtParser() {
-        return mAtParser;
-    }
-
-    public void startEventThread() {
-        mEventThread =
-            new Thread("HeadsetBase Event Thread") {
-                public void run() {
-                    int last_read_error;
-                    while (!mEventThreadInterrupted) {
-                        String input = readNative(500);
-                        if (input != null) {
-                            handleInput(input);
-                        } else {
-                            last_read_error = getLastReadStatusNative();
-                            if (last_read_error != 0) {
-                                Log.i(TAG, "headset read error " + last_read_error);
-                                if (mEventThreadHandler != null) {
-                                    mEventThreadHandler.obtainMessage(RFCOMM_DISCONNECTED)
-                                            .sendToTarget();
-                                }
-                                disconnectNative();
-                                break;
-                            }
-                        }
-                    }
-                }
-            };
-        mEventThreadInterrupted = false;
-        mEventThread.start();
-    }
-
-    private native String readNative(int timeout_ms);
-    private native int getLastReadStatusNative();
-
-    private void stopEventThread() {
-        mEventThreadInterrupted = true;
-        mEventThread.interrupt();
-        try {
-            mEventThread.join();
-        } catch (java.lang.InterruptedException e) {
-            // FIXME: handle this,
-        }
-        mEventThread = null;
-    }
-
-    public boolean connect(Handler handler) {
-        if (mEventThread == null) {
-            if (!connectNative()) return false;
-            mEventThreadHandler = handler;
-        }
-        return true;
-    }
-    private native boolean connectNative();
-
-    /*
-     * Returns true when either the asynchronous connect is in progress, or
-     * the connect is complete.  Call waitForAsyncConnect() to find out whether
-     * the connect is actually complete, or disconnect() to cancel.
-     */
-
-    public boolean connectAsync() {
-        int ret = connectAsyncNative();
-        return (ret == 0) ? true : false;
-    }
-    private native int connectAsyncNative();
-
-    public int getRemainingAsyncConnectWaitingTimeMs() {
-        return mTimeoutRemainingMs;
-    }
-
-    /*
-     * Returns 1 when an async connect is complete, 0 on timeout, and -1 on
-     * error.  On error, handler will be called, and you need to re-initiate
-     * the async connect.
-     */
-    public int waitForAsyncConnect(int timeout_ms, Handler handler) {
-        int res = waitForAsyncConnectNative(timeout_ms);
-        if (res > 0) {
-            mEventThreadHandler = handler;
-        }
-        return res;
-    }
-    private native int waitForAsyncConnectNative(int timeout_ms);
-
-    public void disconnect() {
-        if (mEventThread != null) {
-            stopEventThread();
-        }
-        disconnectNative();
-    }
-    private native void disconnectNative();
-
-
-    /*
-     * Note that if a remote side disconnects, this method will still return
-     * true until disconnect() is called.  You know when a remote side
-     * disconnects because you will receive the intent
-     * IBluetoothService.REMOTE_DEVICE_DISCONNECTED_ACTION.  If, when you get
-     * this intent, method isConnected() returns true, you know that the
-     * disconnect was initiated by the remote device.
-     */
-
-    public boolean isConnected() {
-        return mEventThread != null;
-    }
-
-    public BluetoothDevice getRemoteDevice() {
-        return mRemoteDevice;
-    }
-
-    public int getDirection() {
-        return mDirection;
-    }
-
-    public long getConnectTimestamp() {
-        return mConnectTimestamp;
-    }
-
-    public synchronized boolean sendURC(String urc) {
-        if (urc.length() > 0) {
-            boolean ret = sendURCNative(urc);
-            return ret;
-        }
-        return true;
-    }
-    private native boolean sendURCNative(String urc);
-
-    private synchronized void acquireWakeLock() {
-        if (!mWakeLock.isHeld()) {
-            mWakeLock.acquire();
-        }
-    }
-
-    private synchronized void releaseWakeLock() {
-        if (mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-    }
-
-    public static int getAtInputCount() {
-        return sAtInputCount;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 6075363..d016c26 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -18,9 +18,7 @@
 
 import android.bluetooth.IBluetoothCallback;
 import android.bluetooth.IBluetoothStateChangeCallback;
-import android.bluetooth.IBluetoothHealthCallback;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHealthAppConfiguration;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
 
@@ -32,15 +30,15 @@
 interface IBluetooth
 {
     boolean isEnabled();
-    int getBluetoothState();
+    int getState();
     boolean enable();
     boolean enableNoAutoConnect();
-    boolean disable(boolean persistSetting);
+    boolean disable();
 
     String getAddress();
-    String getName();
-    boolean setName(in String name);
     ParcelUuid[] getUuids();
+    boolean setName(in String name);
+    String getName();
 
     int getScanMode();
     boolean setScanMode(int mode, int duration);
@@ -51,77 +49,34 @@
     boolean startDiscovery();
     boolean cancelDiscovery();
     boolean isDiscovering();
-    byte[] readOutOfBandData();
 
     int getAdapterConnectionState();
     int getProfileConnectionState(int profile);
-    boolean changeApplicationBluetoothState(boolean on,
-                                in IBluetoothStateChangeCallback callback, in
-                                IBinder b);
 
-    boolean createBond(in String address);
-    boolean createBondOutOfBand(in String address, in byte[] hash, in byte[] randomizer);
-    boolean cancelBondProcess(in String address);
-    boolean removeBond(in String address);
-    String[] listBonds();
-    int getBondState(in String address);
-    boolean setDeviceOutOfBandData(in String address, in byte[] hash, in byte[] randomizer);
+    BluetoothDevice[] getBondedDevices();
+    boolean createBond(in BluetoothDevice device);
+    boolean cancelBondProcess(in BluetoothDevice device);
+    boolean removeBond(in BluetoothDevice device);
+    int getBondState(in BluetoothDevice device);
 
-    String getRemoteName(in String address);
-    String getRemoteAlias(in String address);
-    boolean setRemoteAlias(in String address, in String name);
-    int getRemoteClass(in String address);
-    ParcelUuid[] getRemoteUuids(in String address);
-    boolean fetchRemoteUuids(in String address, in ParcelUuid uuid, in IBluetoothCallback callback);
-    int getRemoteServiceChannel(in String address, in ParcelUuid uuid);
+    String getRemoteName(in BluetoothDevice device);
+    String getRemoteAlias(in BluetoothDevice device);
+    boolean setRemoteAlias(in BluetoothDevice device, in String name);
+    int getRemoteClass(in BluetoothDevice device);
+    ParcelUuid[] getRemoteUuids(in BluetoothDevice device);
+    boolean fetchRemoteUuids(in BluetoothDevice device);
 
-    boolean setPin(in String address, in byte[] pin);
-    boolean setPasskey(in String address, int passkey);
-    boolean setPairingConfirmation(in String address, boolean confirm);
-    boolean setRemoteOutOfBandData(in String addres);
-    boolean cancelPairingUserInput(in String address);
-
-    boolean setTrust(in String address, in boolean value);
-    boolean getTrustState(in String address);
-    boolean isBluetoothDock(in String address);
-
-    int addRfcommServiceRecord(in String serviceName, in ParcelUuid uuid, int channel, IBinder b);
-    void removeServiceRecord(int handle);
-    boolean allowIncomingProfileConnect(in BluetoothDevice device, boolean value);
-
-    boolean connectHeadset(String address);
-    boolean disconnectHeadset(String address);
-    boolean notifyIncomingConnection(String address, boolean rejected);
-
-    // HID profile APIs
-    boolean connectInputDevice(in BluetoothDevice device);
-    boolean disconnectInputDevice(in BluetoothDevice device);
-    List<BluetoothDevice> getConnectedInputDevices();
-    List<BluetoothDevice> getInputDevicesMatchingConnectionStates(in int[] states);
-    int getInputDeviceConnectionState(in BluetoothDevice device);
-    boolean setInputDevicePriority(in BluetoothDevice device, int priority);
-    int getInputDevicePriority(in BluetoothDevice device);
-
-    boolean isTetheringOn();
-    void setBluetoothTethering(boolean value);
-    int getPanDeviceConnectionState(in BluetoothDevice device);
-    List<BluetoothDevice> getConnectedPanDevices();
-    List<BluetoothDevice> getPanDevicesMatchingConnectionStates(in int[] states);
-    boolean connectPanDevice(in BluetoothDevice device);
-    boolean disconnectPanDevice(in BluetoothDevice device);
-
-    // HDP profile APIs
-    boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config,
-        in IBluetoothHealthCallback callback);
-    boolean unregisterAppConfiguration(in BluetoothHealthAppConfiguration config);
-    boolean connectChannelToSource(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
-    boolean connectChannelToSink(in BluetoothDevice device, in BluetoothHealthAppConfiguration config,
-        int channelType);
-    boolean disconnectChannel(in BluetoothDevice device, in BluetoothHealthAppConfiguration config, int id);
-    ParcelFileDescriptor getMainChannelFd(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
-    List<BluetoothDevice> getConnectedHealthDevices();
-    List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(in int[] states);
-    int getHealthDeviceConnectionState(in BluetoothDevice device);
+    boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
+    boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
+    passkey);
+    boolean setPairingConfirmation(in BluetoothDevice device, boolean accept);
 
     void sendConnectionStateChange(in BluetoothDevice device, int profile, int state, int prevState);
+
+    void registerCallback(in IBluetoothCallback callback);
+    void unregisterCallback(in IBluetoothCallback callback);
+
+    // For Socket
+    ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);
+    ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
 }
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 444dd1e..1f10998 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -33,12 +33,4 @@
     boolean setPriority(in BluetoothDevice device, int priority);
     int getPriority(in BluetoothDevice device);
     boolean isA2dpPlaying(in BluetoothDevice device);
-
-    // Internal APIs
-    boolean suspendSink(in BluetoothDevice device);
-    boolean resumeSink(in BluetoothDevice device);
-    boolean connectSinkInternal(in BluetoothDevice device);
-    boolean disconnectSinkInternal(in BluetoothDevice device);
-    boolean allowIncomingConnect(in BluetoothDevice device, boolean value);
-
 }
diff --git a/core/java/android/bluetooth/IBluetoothCallback.aidl b/core/java/android/bluetooth/IBluetoothCallback.aidl
index 8edb3f4..e280978 100644
--- a/core/java/android/bluetooth/IBluetoothCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothCallback.aidl
@@ -23,5 +23,6 @@
  */
 interface IBluetoothCallback
 {
-    void onRfcommChannelFound(int channel);
+    //void onRfcommChannelFound(int channel);
+    void onBluetoothStateChange(int prevState, int newState);
 }
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index ec00527..fc7627a 100644
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -40,15 +40,17 @@
     int getBatteryUsageHint(in BluetoothDevice device);
 
     // Internal functions, not be made public
-    boolean createIncomingConnect(in BluetoothDevice device);
     boolean acceptIncomingConnect(in BluetoothDevice device);
     boolean rejectIncomingConnect(in BluetoothDevice device);
-    boolean cancelConnectThread();
-    boolean connectHeadsetInternal(in BluetoothDevice device);
-    boolean disconnectHeadsetInternal(in BluetoothDevice device);
-    boolean setAudioState(in BluetoothDevice device, int state);
     int getAudioState(in BluetoothDevice device);
 
+    boolean isAudioOn();
+    boolean connectAudio();
+    boolean disconnectAudio();
     boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
     boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
+    void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
+    void roamChanged(boolean roam);
+    void clccResponse(int index, int direction, int status, int mode, boolean mpty,
+                      String number, int type);
 }
diff --git a/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl b/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl
new file mode 100644
index 0000000..163e4e2
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothHeadsetPhone.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+
+package android.bluetooth;
+
+/**
+ * API for Bluetooth Headset Phone Service in phone app
+ *
+ * {@hide}
+ */
+interface IBluetoothHeadsetPhone {
+  // Internal functions, not be made public
+  boolean answerCall();
+  boolean hangupCall();
+  boolean sendDtmf(int dtmf);
+  boolean processChld(int chld);
+  String getNetworkOperator();
+  String getSubscriberNumber();
+  boolean listCurrentCalls();
+  boolean queryPhoneState();
+
+  // Internal for phone app to call
+  void updateBtHandsfreeAfterRadioTechnologyChange();
+  void cdmaSwapSecondCallState();
+  void cdmaSetSecondCallState(boolean state);
+}
diff --git a/core/java/android/bluetooth/IBluetoothHealth.aidl b/core/java/android/bluetooth/IBluetoothHealth.aidl
new file mode 100644
index 0000000..e741da4
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothHealth.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHealthAppConfiguration;
+import android.bluetooth.IBluetoothHealthCallback;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * API for Bluetooth Health service
+ *
+ * {@hide}
+ */
+interface IBluetoothHealth
+{
+    boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config,
+        in IBluetoothHealthCallback callback);
+    boolean unregisterAppConfiguration(in BluetoothHealthAppConfiguration config);
+    boolean connectChannelToSource(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
+    boolean connectChannelToSink(in BluetoothDevice device, in BluetoothHealthAppConfiguration config,
+        int channelType);
+    boolean disconnectChannel(in BluetoothDevice device, in BluetoothHealthAppConfiguration config, int id);
+    ParcelFileDescriptor getMainChannelFd(in BluetoothDevice device, in BluetoothHealthAppConfiguration config);
+    List<BluetoothDevice> getConnectedHealthDevices();
+    List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(in int[] states);
+    int getHealthDeviceConnectionState(in BluetoothDevice device);
+}
diff --git a/core/java/android/bluetooth/IBluetoothInputDevice.aidl b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
new file mode 100755
index 0000000..23e6d50
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothInputDevice.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * API for Bluetooth HID service
+ *
+ * {@hide}
+ */
+interface IBluetoothInputDevice {
+    // Public API
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device, int priority);
+    int getPriority(in BluetoothDevice device);
+    /**
+    * @hide
+    */
+    boolean getProtocolMode(in BluetoothDevice device);
+    /**
+    * @hide
+    */
+    boolean virtualUnplug(in BluetoothDevice device);
+    /**
+    * @hide
+    */
+    boolean setProtocolMode(in BluetoothDevice device, int protocolMode);
+    /**
+    * @hide
+    */
+    boolean getReport(in BluetoothDevice device, byte reportType, byte reportId, int bufferSize);
+    /**
+    * @hide
+    */
+    boolean setReport(in BluetoothDevice device, byte reportType, String report);
+    /**
+    * @hide
+    */
+    boolean sendData(in BluetoothDevice device, String report);
+}
diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl
new file mode 100644
index 0000000..f82da82
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothManager.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothManagerCallback;
+import android.bluetooth.IBluetoothStateChangeCallback;
+
+/**
+ * System private API for talking with the Bluetooth service.
+ *
+ * {@hide}
+ */
+interface IBluetoothManager
+{
+    IBluetooth registerAdapter(in IBluetoothManagerCallback callback);
+    void unregisterAdapter(in IBluetoothManagerCallback callback);
+    void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);
+    void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);
+    boolean isEnabled();
+    boolean enable();
+    boolean disable(boolean persist);
+
+    String getAddress();
+    String getName();
+}
diff --git a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
new file mode 100644
index 0000000..3e795ea
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.IBluetooth;
+
+/**
+ * API for Communication between BluetoothAdapter and BluetoothManager
+ *
+ * {@hide}
+ */
+interface IBluetoothManagerCallback {
+    void onBluetoothServiceUp(in IBluetooth bluetoothService);
+    void onBluetoothServiceDown();
+}
\ No newline at end of file
diff --git a/core/java/android/bluetooth/IBluetoothPan.aidl b/core/java/android/bluetooth/IBluetoothPan.aidl
new file mode 100644
index 0000000..b91bd7d
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothPan.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * API for Bluetooth Pan service
+ *
+ * {@hide}
+ */
+interface IBluetoothPan {
+    // Public API
+    boolean isTetheringOn();
+    void setBluetoothTethering(boolean value);
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 66fed818..490165d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1907,6 +1907,15 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.bluetooth.BluetoothAdapter} for using Bluetooth.
+     *
+     * @see #getSystemService
+     * @hide
+     */
+    public static final String BLUETOOTH_SERVICE = "bluetooth";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.net.sip.SipManager} for accessing the SIP related service.
      *
      * @see #getSystemService
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 5f8793c..fa1ff85 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -137,6 +137,28 @@
     public static final String EXTRA_INET_CONDITION = "inetCondition";
 
     /**
+     * Broadcast action to indicate the change of data activity status
+     * (idle or active) on a network in a recent period.
+     * The network becomes active when data transimission is started, or
+     * idle if there is no data transimition for a period of time.
+     * {@hide}
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
+    /**
+     * The lookup key for an enum that indicates the network device type on which this data activity
+     * change happens.
+     * {@hide}
+     */
+    public static final String EXTRA_DEVICE_TYPE = "deviceType";
+    /**
+     * The lookup key for a boolean that indicates the device is active or not. {@code true} means
+     * it is actively sending or receiving data and {@code false} means it is idle.
+     * {@hide}
+     */
+    public static final String EXTRA_IS_ACTIVE = "isActive";
+
+    /**
      * Broadcast Action: The setting for background data usage has changed
      * values. Use {@link #getBackgroundDataSetting()} to get the current value.
      * <p>
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 5197c9e..c690430 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -99,6 +99,10 @@
         public void limitReached(String limitName, String iface) {
             // Ignored.
         }
+
+        public void interfaceClassDataActivityChanged(String label, boolean active) {
+            // Ignored.
+        }
     }
 
     private EthernetDataTracker() {
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index a97f203..6f4dd5f 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -62,4 +62,11 @@
      */
     void limitReached(String limitName, String iface);
 
+    /**
+     * Interface data activity status is changed.
+     *
+     * @param iface The interface.
+     * @param active  True if the interface is actively transmitting data, false if it is idle.
+     */
+    void interfaceClassDataActivityChanged(String label, boolean active);
 }
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index 3ee8a80..34e0d9a 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -42,6 +42,15 @@
         isBound = false;
         isConnected = false;
     }
+    /**
+     * Creates a AF_LOCAL/UNIX domain stream socket with FileDescriptor.
+     * @hide
+     */
+    public LocalSocket(FileDescriptor fd) throws IOException {
+        this(new LocalSocketImpl(fd));
+        isBound = true;
+        isConnected = true;
+    }
 
     /**
      * for use with AndroidServerSocket
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index b64a73a..53bb88a 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -152,6 +152,16 @@
     boolean isTetheringStarted();
 
     /**
+     * Start bluetooth reverse tethering services
+     */
+    void startReverseTethering(in String iface);
+
+    /**
+     * Stop currently running bluetooth reserse tethering services
+     */
+    void stopReverseTethering();
+
+    /**
      * Tethers the specified interface
      */
     void tetherInterface(String iface);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 6ab4dc1..a04ad93 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -116,6 +116,12 @@
     public static final int NFC_UID = 1027;
 
     /**
+     * Defines the UID/GID for the Bluetooth service process.
+     * @hide
+     */
+    public static final int BLUETOOTH_UID = 1002;
+
+    /**
      * Defines the GID for the group that allows write access to the internal media storage.
      * @hide
      */
diff --git a/core/java/android/os/SchedulingPolicyService.java b/core/java/android/os/SchedulingPolicyService.java
index 94f907b..a3fede6 100644
--- a/core/java/android/os/SchedulingPolicyService.java
+++ b/core/java/android/os/SchedulingPolicyService.java
@@ -33,7 +33,7 @@
 
     // Minimum and maximum values allowed for requestPriority parameter prio
     private static final int PRIORITY_MIN = 1;
-    private static final int PRIORITY_MAX = 2;
+    private static final int PRIORITY_MAX = 3;
 
     public SchedulingPolicyService() {
     }
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
deleted file mode 100644
index 08a99d2..0000000
--- a/core/java/android/server/BluetoothA2dpService.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * TODO: Move this to services.jar
- * and make the constructor package private again.
- * @hide
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetoothA2dp;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelUuid;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-
-public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
-    private static final String TAG = "BluetoothA2dpService";
-    private static final boolean DBG = true;
-
-    public static final String BLUETOOTH_A2DP_SERVICE = "bluetooth_a2dp";
-
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
-    private static final String BLUETOOTH_ENABLED = "bluetooth_enabled";
-
-    private static final String PROPERTY_STATE = "State";
-
-    private final Context mContext;
-    private final IntentFilter mIntentFilter;
-    private HashMap<BluetoothDevice, Integer> mAudioDevices;
-    private final AudioManager mAudioManager;
-    private final BluetoothService mBluetoothService;
-    private final BluetoothAdapter mAdapter;
-    private int   mTargetA2dpState;
-    private BluetoothDevice mPlayingA2dpDevice;
-    private IntentBroadcastHandler mIntentBroadcastHandler;
-    private final WakeLock mWakeLock;
-
-    private static final int MSG_CONNECTION_STATE_CHANGED = 0;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            BluetoothDevice device =
-                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                               BluetoothAdapter.ERROR);
-                switch (state) {
-                case BluetoothAdapter.STATE_ON:
-                    onBluetoothEnable();
-                    break;
-                case BluetoothAdapter.STATE_TURNING_OFF:
-                    onBluetoothDisable();
-                    break;
-                }
-            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
-                synchronized (this) {
-                    if (mAudioDevices.containsKey(device)) {
-                        int state = mAudioDevices.get(device);
-                        handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
-                    }
-                }
-            } else if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
-                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
-                if (streamType == AudioManager.STREAM_MUSIC) {
-                    List<BluetoothDevice> sinks = getConnectedDevices();
-
-                    if (sinks.size() != 0 && isPhoneDocked(sinks.get(0))) {
-                        String address = sinks.get(0).getAddress();
-                        int newVolLevel =
-                          intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
-                        int oldVolLevel =
-                          intent.getIntExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
-                        String path = mBluetoothService.getObjectPathFromAddress(address);
-                        if (newVolLevel > oldVolLevel) {
-                            avrcpVolumeUpNative(path);
-                        } else if (newVolLevel < oldVolLevel) {
-                            avrcpVolumeDownNative(path);
-                        }
-                    }
-                }
-            }
-        }
-    };
-
-    private boolean isPhoneDocked(BluetoothDevice device) {
-        // This works only because these broadcast intents are "sticky"
-        Intent i = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
-        if (i != null) {
-            int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
-            if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                BluetoothDevice dockDevice = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                if (dockDevice != null && device.equals(dockDevice)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {
-        mContext = context;
-
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BluetoothA2dpService");
-
-        mIntentBroadcastHandler = new IntentBroadcastHandler();
-
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-
-        mBluetoothService = bluetoothService;
-        if (mBluetoothService == null) {
-            throw new RuntimeException("Platform does not support Bluetooth");
-        }
-
-        if (!initNative()) {
-            throw new RuntimeException("Could not init BluetoothA2dpService");
-        }
-
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
-        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
-        mIntentFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-
-        mAudioDevices = new HashMap<BluetoothDevice, Integer>();
-
-        if (mBluetoothService.isEnabled())
-            onBluetoothEnable();
-        mTargetA2dpState = -1;
-        mBluetoothService.setA2dpService(this);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            cleanupNative();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    private int convertBluezSinkStringToState(String value) {
-        if (value.equalsIgnoreCase("disconnected"))
-            return BluetoothA2dp.STATE_DISCONNECTED;
-        if (value.equalsIgnoreCase("connecting"))
-            return BluetoothA2dp.STATE_CONNECTING;
-        if (value.equalsIgnoreCase("connected"))
-            return BluetoothA2dp.STATE_CONNECTED;
-        if (value.equalsIgnoreCase("playing"))
-            return BluetoothA2dp.STATE_PLAYING;
-        return -1;
-    }
-
-    private boolean isSinkDevice(BluetoothDevice device) {
-        ParcelUuid[] uuids = mBluetoothService.getRemoteUuids(device.getAddress());
-        if (uuids != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) {
-            return true;
-        }
-        return false;
-    }
-
-    private synchronized void addAudioSink(BluetoothDevice device) {
-        if (mAudioDevices.get(device) == null) {
-            mAudioDevices.put(device, BluetoothA2dp.STATE_DISCONNECTED);
-        }
-    }
-
-    private synchronized void onBluetoothEnable() {
-        String devices = mBluetoothService.getProperty("Devices", true);
-        if (devices != null) {
-            String [] paths = devices.split(",");
-            for (String path: paths) {
-                String address = mBluetoothService.getAddressFromObjectPath(path);
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                ParcelUuid[] remoteUuids = mBluetoothService.getRemoteUuids(address);
-                if (remoteUuids != null)
-                    if (BluetoothUuid.containsAnyUuid(remoteUuids,
-                            new ParcelUuid[] {BluetoothUuid.AudioSink,
-                                                BluetoothUuid.AdvAudioDist})) {
-                        addAudioSink(device);
-                    }
-                }
-        }
-        mAudioManager.setParameters(BLUETOOTH_ENABLED+"=true");
-        mAudioManager.setParameters("A2dpSuspended=false");
-    }
-
-    private synchronized void onBluetoothDisable() {
-        if (!mAudioDevices.isEmpty()) {
-            BluetoothDevice[] devices = new BluetoothDevice[mAudioDevices.size()];
-            devices = mAudioDevices.keySet().toArray(devices);
-            for (BluetoothDevice device : devices) {
-                int state = getConnectionState(device);
-                switch (state) {
-                    case BluetoothA2dp.STATE_CONNECTING:
-                    case BluetoothA2dp.STATE_CONNECTED:
-                    case BluetoothA2dp.STATE_PLAYING:
-                        disconnectSinkNative(mBluetoothService.getObjectPathFromAddress(
-                                device.getAddress()));
-                        handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
-                        break;
-                    case BluetoothA2dp.STATE_DISCONNECTING:
-                        handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTING,
-                                              BluetoothA2dp.STATE_DISCONNECTED);
-                        break;
-                }
-            }
-            mAudioDevices.clear();
-        }
-
-        mAudioManager.setParameters(BLUETOOTH_ENABLED + "=false");
-    }
-
-    private synchronized boolean isConnectSinkFeasible(BluetoothDevice device) {
-        if (!mBluetoothService.isEnabled() || !isSinkDevice(device) ||
-                getPriority(device) == BluetoothA2dp.PRIORITY_OFF) {
-            return false;
-        }
-
-        addAudioSink(device);
-
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (path == null) {
-            return false;
-        }
-        return true;
-    }
-
-    public synchronized boolean isA2dpPlaying(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-            "Need BLUETOOTH_ADMIN permission");
-        if (DBG) log("isA2dpPlaying(" + device + ")");
-        if (device.equals(mPlayingA2dpDevice)) return true;
-        return false;
-    }
-
-    public synchronized boolean connect(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (DBG) log("connectSink(" + device + ")");
-        if (!isConnectSinkFeasible(device)) return false;
-
-        for (BluetoothDevice sinkDevice : mAudioDevices.keySet()) {
-            if (getConnectionState(sinkDevice) != BluetoothProfile.STATE_DISCONNECTED) {
-                disconnect(sinkDevice);
-            }
-        }
-
-        return mBluetoothService.connectSink(device.getAddress());
-    }
-
-    public synchronized boolean connectSinkInternal(BluetoothDevice device) {
-        if (!mBluetoothService.isEnabled()) return false;
-
-        int state = mAudioDevices.get(device);
-
-        // ignore if there are any active sinks
-        if (getDevicesMatchingConnectionStates(new int[] {
-                BluetoothA2dp.STATE_CONNECTING,
-                BluetoothA2dp.STATE_CONNECTED,
-                BluetoothA2dp.STATE_DISCONNECTING}).size() != 0) {
-            return false;
-        }
-
-        switch (state) {
-        case BluetoothA2dp.STATE_CONNECTED:
-        case BluetoothA2dp.STATE_DISCONNECTING:
-            return false;
-        case BluetoothA2dp.STATE_CONNECTING:
-            return true;
-        }
-
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-
-        // State is DISCONNECTED and we are connecting.
-        if (getPriority(device) < BluetoothA2dp.PRIORITY_AUTO_CONNECT) {
-            setPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
-        }
-        handleSinkStateChange(device, state, BluetoothA2dp.STATE_CONNECTING);
-
-        if (!connectSinkNative(path)) {
-            // Restore previous state
-            handleSinkStateChange(device, mAudioDevices.get(device), state);
-            return false;
-        }
-        return true;
-    }
-
-    private synchronized boolean isDisconnectSinkFeasible(BluetoothDevice device) {
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (path == null) {
-            return false;
-        }
-
-        int state = getConnectionState(device);
-        switch (state) {
-        case BluetoothA2dp.STATE_DISCONNECTED:
-        case BluetoothA2dp.STATE_DISCONNECTING:
-            return false;
-        }
-        return true;
-    }
-
-    public synchronized boolean disconnect(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (DBG) log("disconnectSink(" + device + ")");
-        if (!isDisconnectSinkFeasible(device)) return false;
-        return mBluetoothService.disconnectSink(device.getAddress());
-    }
-
-    public synchronized boolean disconnectSinkInternal(BluetoothDevice device) {
-        int state = getConnectionState(device);
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-
-        switch (state) {
-            case BluetoothA2dp.STATE_DISCONNECTED:
-            case BluetoothA2dp.STATE_DISCONNECTING:
-                return false;
-        }
-        // State is CONNECTING or CONNECTED or PLAYING
-        handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTING);
-        if (!disconnectSinkNative(path)) {
-            // Restore previous state
-            handleSinkStateChange(device, mAudioDevices.get(device), state);
-            return false;
-        }
-        return true;
-    }
-
-    public synchronized boolean suspendSink(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                            "Need BLUETOOTH_ADMIN permission");
-        if (DBG) log("suspendSink(" + device + "), mTargetA2dpState: "+mTargetA2dpState);
-        if (device == null || mAudioDevices == null) {
-            return false;
-        }
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        Integer state = mAudioDevices.get(device);
-        if (path == null || state == null) {
-            return false;
-        }
-
-        mTargetA2dpState = BluetoothA2dp.STATE_CONNECTED;
-        return checkSinkSuspendState(state.intValue());
-    }
-
-    public synchronized boolean resumeSink(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                            "Need BLUETOOTH_ADMIN permission");
-        if (DBG) log("resumeSink(" + device + "), mTargetA2dpState: "+mTargetA2dpState);
-        if (device == null || mAudioDevices == null) {
-            return false;
-        }
-        String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        Integer state = mAudioDevices.get(device);
-        if (path == null || state == null) {
-            return false;
-        }
-        mTargetA2dpState = BluetoothA2dp.STATE_PLAYING;
-        return checkSinkSuspendState(state.intValue());
-    }
-
-    public synchronized int getConnectionState(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        Integer state = mAudioDevices.get(device);
-        if (state == null)
-            return BluetoothA2dp.STATE_DISCONNECTED;
-        return state;
-    }
-
-    public synchronized List<BluetoothDevice> getConnectedDevices() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        List<BluetoothDevice> sinks = getDevicesMatchingConnectionStates(
-                new int[] {BluetoothA2dp.STATE_CONNECTED});
-        return sinks;
-    }
-
-    public synchronized List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        ArrayList<BluetoothDevice> sinks = new ArrayList<BluetoothDevice>();
-        for (BluetoothDevice device: mAudioDevices.keySet()) {
-            int sinkState = getConnectionState(device);
-            for (int state : states) {
-                if (state == sinkState) {
-                    sinks.add(device);
-                    break;
-                }
-            }
-        }
-        return sinks;
-    }
-
-    public synchronized int getPriority(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
-                BluetoothA2dp.PRIORITY_UNDEFINED);
-    }
-
-    public synchronized boolean setPriority(BluetoothDevice device, int priority) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        return Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority);
-    }
-
-    public synchronized boolean allowIncomingConnect(BluetoothDevice device, boolean value) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        String address = device.getAddress();
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        Integer data = mBluetoothService.getAuthorizationAgentRequestData(address);
-        if (data == null) {
-            Log.w(TAG, "allowIncomingConnect(" + device + ") called but no native data available");
-            return false;
-        }
-        log("allowIncomingConnect: A2DP: " + device + ":" + value);
-        return mBluetoothService.setAuthorizationNative(address, value, data.intValue());
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.AudioSink.
-     *
-     * @param path the object path for the changed device
-     * @param propValues a string array containing the key and one or more
-     *  values.
-     */
-    private synchronized void onSinkPropertyChanged(String path, String[] propValues) {
-        if (!mBluetoothService.isEnabled()) {
-            return;
-        }
-
-        String name = propValues[0];
-        String address = mBluetoothService.getAddressFromObjectPath(path);
-        if (address == null) {
-            Log.e(TAG, "onSinkPropertyChanged: Address of the remote device in null");
-            return;
-        }
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-
-        if (name.equals(PROPERTY_STATE)) {
-            int state = convertBluezSinkStringToState(propValues[1]);
-            log("A2DP: onSinkPropertyChanged newState is: " + state + "mPlayingA2dpDevice: " + mPlayingA2dpDevice);
-
-            if (mAudioDevices.get(device) == null) {
-                // This is for an incoming connection for a device not known to us.
-                // We have authorized it and bluez state has changed.
-                addAudioSink(device);
-                handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTED, state);
-            } else {
-                if (state == BluetoothA2dp.STATE_PLAYING && mPlayingA2dpDevice == null) {
-                   mPlayingA2dpDevice = device;
-                   handleSinkPlayingStateChange(device, state, BluetoothA2dp.STATE_NOT_PLAYING);
-                } else if (state == BluetoothA2dp.STATE_CONNECTED && mPlayingA2dpDevice != null) {
-                    mPlayingA2dpDevice = null;
-                    handleSinkPlayingStateChange(device, BluetoothA2dp.STATE_NOT_PLAYING,
-                        BluetoothA2dp.STATE_PLAYING);
-                } else {
-                   mPlayingA2dpDevice = null;
-                   int prevState = mAudioDevices.get(device);
-                   handleSinkStateChange(device, prevState, state);
-                }
-            }
-        }
-    }
-
-    private void handleSinkStateChange(BluetoothDevice device, int prevState, int state) {
-        if (state != prevState) {
-            mAudioDevices.put(device, state);
-
-            checkSinkSuspendState(state);
-            mTargetA2dpState = -1;
-
-            if (getPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
-                    state == BluetoothA2dp.STATE_CONNECTED) {
-                // We have connected or attempting to connect.
-                // Bump priority
-                setPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
-                // We will only have 1 device with AUTO_CONNECT priority
-                // To be backward compatible set everyone else to have PRIORITY_ON
-                adjustOtherSinkPriorities(device);
-            }
-
-            int delay = mAudioManager.setBluetoothA2dpDeviceConnectionState(device, state);
-
-            mWakeLock.acquire();
-            mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage(
-                                                            MSG_CONNECTION_STATE_CHANGED,
-                                                            prevState,
-                                                            state,
-                                                            device),
-                                                       delay);
-        }
-    }
-
-    private void handleSinkPlayingStateChange(BluetoothDevice device, int state, int prevState) {
-        Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
-        intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-
-        if (DBG) log("A2DP Playing state : device: " + device + " State:" + prevState + "->" + state);
-    }
-
-    private void adjustOtherSinkPriorities(BluetoothDevice connectedDevice) {
-        for (BluetoothDevice device : mAdapter.getBondedDevices()) {
-            if (getPriority(device) >= BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
-                !device.equals(connectedDevice)) {
-                setPriority(device, BluetoothA2dp.PRIORITY_ON);
-            }
-        }
-    }
-
-    private boolean checkSinkSuspendState(int state) {
-        boolean result = true;
-
-        if (state != mTargetA2dpState) {
-            if (state == BluetoothA2dp.STATE_PLAYING &&
-                mTargetA2dpState == BluetoothA2dp.STATE_CONNECTED) {
-                mAudioManager.setParameters("A2dpSuspended=true");
-            } else if (state == BluetoothA2dp.STATE_CONNECTED &&
-                mTargetA2dpState == BluetoothA2dp.STATE_PLAYING) {
-                mAudioManager.setParameters("A2dpSuspended=false");
-            } else {
-                result = false;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Called by native code for the async response to a Connect
-     * method call to org.bluez.AudioSink.
-     *
-     * @param deviceObjectPath the object path for the connecting device
-     * @param result true on success; false on error
-     */
-    private void onConnectSinkResult(String deviceObjectPath, boolean result) {
-        // If the call was a success, ignore we will update the state
-        // when we a Sink Property Change
-        if (!result) {
-            if (deviceObjectPath != null) {
-                String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-                if (address == null) return;
-                BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                int state = getConnectionState(device);
-                handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
-            }
-        }
-    }
-
-    /** Handles A2DP connection state change intent broadcasts. */
-    private class IntentBroadcastHandler extends Handler {
-
-        private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
-            Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
-            intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-
-            if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
-
-            mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
-                                                        prevState);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_CONNECTION_STATE_CHANGED:
-                    onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2);
-                    mWakeLock.release();
-                    break;
-            }
-        }
-    }
-
-    @Override
-    protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-        if (mAudioDevices.isEmpty()) return;
-        pw.println("Cached audio devices:");
-        for (BluetoothDevice device : mAudioDevices.keySet()) {
-            int state = mAudioDevices.get(device);
-            pw.println(device + " " + BluetoothA2dp.stateToString(state));
-        }
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private native boolean initNative();
-    private native void cleanupNative();
-    private synchronized native boolean connectSinkNative(String path);
-    private synchronized native boolean disconnectSinkNative(String path);
-    private synchronized native boolean suspendSinkNative(String path);
-    private synchronized native boolean resumeSinkNative(String path);
-    private synchronized native Object []getSinkPropertiesNative(String path);
-    private synchronized native boolean avrcpVolumeUpNative(String path);
-    private synchronized native boolean avrcpVolumeDownNative(String path);
-}
diff --git a/core/java/android/server/BluetoothAdapterProperties.java b/core/java/android/server/BluetoothAdapterProperties.java
deleted file mode 100644
index 9723f60..0000000
--- a/core/java/android/server/BluetoothAdapterProperties.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.content.Context;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-
-class BluetoothAdapterProperties {
-
-    private static final String TAG = "BluetoothAdapterProperties";
-
-    private final Map<String, String> mPropertiesMap;
-    private final Context mContext;
-    private final BluetoothService mService;
-
-    BluetoothAdapterProperties(Context context, BluetoothService service) {
-        mPropertiesMap = new HashMap<String, String>();
-        mContext = context;
-        mService = service;
-    }
-
-    synchronized String getProperty(String name) {
-        if (mPropertiesMap.isEmpty()) {
-            getAllProperties();
-        }
-        return mPropertiesMap.get(name);
-    }
-
-    String getObjectPath() {
-        return getProperty("ObjectPath");
-    }
-
-    synchronized void clear() {
-        mPropertiesMap.clear();
-    }
-
-    synchronized boolean isEmpty() {
-        return mPropertiesMap.isEmpty();
-    }
-
-    synchronized void setProperty(String name, String value) {
-        mPropertiesMap.put(name, value);
-    }
-
-    synchronized void getAllProperties() {
-        mContext.enforceCallingOrSelfPermission(
-                BluetoothService.BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        mPropertiesMap.clear();
-
-        String properties[] = (String[]) mService
-                .getAdapterPropertiesNative();
-        // The String Array consists of key-value pairs.
-        if (properties == null) {
-            Log.e(TAG, "*Error*: GetAdapterProperties returned NULL");
-            return;
-        }
-
-        for (int i = 0; i < properties.length; i++) {
-            String name = properties[i];
-            String newValue = null;
-            if (name == null) {
-                Log.e(TAG, "Error:Adapter Property at index " + i + " is null");
-                continue;
-            }
-            if (name.equals("Devices") || name.equals("UUIDs")) {
-                StringBuilder str = new StringBuilder();
-                int len = Integer.valueOf(properties[++i]);
-                for (int j = 0; j < len; j++) {
-                    str.append(properties[++i]);
-                    str.append(",");
-                }
-                if (len > 0) {
-                    newValue = str.toString();
-                }
-            } else {
-                newValue = properties[++i];
-            }
-            mPropertiesMap.put(name, newValue);
-        }
-
-        // Add adapter object path property.
-        String adapterPath = mService.getAdapterPathNative();
-        if (adapterPath != null) {
-            mPropertiesMap.put("ObjectPath", adapterPath + "/dev_");
-        }
-    }
-}
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
deleted file mode 100644
index 1de1839..0000000
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.util.IState;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.PrintWriter;
-
-/**
- * Bluetooth Adapter StateMachine
- * All the states are at the same level, ie, no hierarchy.
- *                         (BluetootOn)<----------------------<-
- *                           |    ^    -------------------->-  |
- *                           |    |                         |  |
- *            USER_TURN_OFF  |    | SCAN_MODE_CHANGED    m1 |  | USER_TURN_ON
- *         AIRPLANE_MODE_ON  |    |                         |  |
- *                           V    |                         |  |
- *                         (Switching)                   (PerProcessState)
- *                           |    ^                         |  |
- *     POWER_STATE_CHANGED & |    | TURN_ON(_CONTINUE)      |  |
- * ALL_DEVICES_DISCONNECTED  |    |                     m2  |  |
- *                           V    |------------------------<   | SCAN_MODE_CHANGED
- *                          (HotOff)-------------------------->- PER_PROCESS_TURN_ON
- *                           /    ^
- *                          /     |  SERVICE_RECORD_LOADED
- *                         |      |
- *              TURN_COLD  |   (Warmup)
- *                         \      ^
- *                          \     |  TURN_HOT/TURN_ON
- *                           |    |  AIRPLANE_MODE_OFF(when Bluetooth was on before)
- *                           V    |
- *                           (PowerOff)   <----- initial state
- *
- * Legend:
- * m1 = TURN_HOT
- * m2 = Transition to HotOff when number of process wanting BT on is 0.
- *      POWER_STATE_CHANGED will make the transition.
- * Note:
- * The diagram above shows all the states and messages that trigger normal state changes.
- * The diagram above does not capture everything:
- *   The diagram does not capture following messages.
- *   - messages that do not trigger state changes
- *     For example, PER_PROCESS_TURN_ON received in BluetoothOn state
- *   - unhandled messages
- *     For example, USER_TURN_ON received in BluetoothOn state
- *   - timeout messages
- *   The diagram does not capture error conditions and state recoveries.
- *   - For example POWER_STATE_CHANGED received in BluetoothOn state
- */
-final class BluetoothAdapterStateMachine extends StateMachine {
-    private static final String TAG = "BluetoothAdapterStateMachine";
-    private static final boolean DBG = false;
-
-    // Message(what) to take an action
-    //
-    // We get this message when user tries to turn on BT
-    static final int USER_TURN_ON = 1;
-    // We get this message when user tries to turn off BT
-    static final int USER_TURN_OFF = 2;
-    // Per process enable / disable messages
-    static final int PER_PROCESS_TURN_ON = 3;
-    static final int PER_PROCESS_TURN_OFF = 4;
-
-    // Turn on Bluetooth Module, Load firmware, and do all the preparation
-    // needed to get the Bluetooth Module ready but keep it not discoverable
-    // and not connectable. This way the Bluetooth Module can be quickly
-    // switched on if needed
-    static final int TURN_HOT = 5;
-
-    // Message(what) to report a event that the state machine need to respond to
-    //
-    // Event indicates sevice records have been loaded
-    static final int SERVICE_RECORD_LOADED = 51;
-    // Event indicates all the remote Bluetooth devices has been disconnected
-    static final int ALL_DEVICES_DISCONNECTED = 52;
-    // Event indicates the Bluetooth scan mode has changed
-    static final int SCAN_MODE_CHANGED = 53;
-    // Event indicates the powered state has changed
-    static final int POWER_STATE_CHANGED = 54;
-    // Event indicates airplane mode is turned on
-    static final int AIRPLANE_MODE_ON = 55;
-    // Event indicates airplane mode is turned off
-    static final int AIRPLANE_MODE_OFF = 56;
-
-    // private internal messages
-    //
-    // USER_TURN_ON is changed to TURN_ON_CONTINUE after we broadcast the
-    // state change intent so that we will not broadcast the intent again in
-    // other state
-    private static final int TURN_ON_CONTINUE = 101;
-    // Unload firmware, turning off Bluetooth module power
-    private static final int TURN_COLD = 102;
-    // Device disconnecting timeout happens
-    private static final int DEVICES_DISCONNECT_TIMEOUT = 103;
-    // Prepare Bluetooth timeout happens
-    private static final int PREPARE_BLUETOOTH_TIMEOUT = 104;
-    // Bluetooth turn off wait timeout happens
-    private static final int TURN_OFF_TIMEOUT = 105;
-    // Bluetooth device power off wait timeout happens
-    private static final int POWER_DOWN_TIMEOUT = 106;
-
-    private Context mContext;
-    private BluetoothService mBluetoothService;
-    private BluetoothEventLoop mEventLoop;
-
-    private BluetoothOn mBluetoothOn;
-    private Switching mSwitching;
-    private HotOff mHotOff;
-    private WarmUp mWarmUp;
-    private PowerOff mPowerOff;
-    private PerProcessState mPerProcessState;
-
-    // this is the BluetoothAdapter state that reported externally
-    private int mPublicState;
-    // When turning off, broadcast STATE_OFF in the last HotOff state
-    // This is because we do HotOff -> PowerOff -> HotOff for USER_TURN_OFF
-    private boolean mDelayBroadcastStateOff;
-
-    // timeout value waiting for all the devices to be disconnected
-    private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000;
-
-    private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000;
-
-    private static final int TURN_OFF_TIMEOUT_TIME = 5000;
-    private static final int POWER_DOWN_TIMEOUT_TIME = 20;
-
-    BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
-                                 BluetoothAdapter bluetoothAdapter) {
-        super(TAG);
-        mContext = context;
-        mBluetoothService = bluetoothService;
-        mEventLoop = new BluetoothEventLoop(context, bluetoothAdapter, bluetoothService, this);
-
-        mBluetoothOn = new BluetoothOn();
-        mSwitching = new Switching();
-        mHotOff = new HotOff();
-        mWarmUp = new WarmUp();
-        mPowerOff = new PowerOff();
-        mPerProcessState = new PerProcessState();
-
-        addState(mBluetoothOn);
-        addState(mSwitching);
-        addState(mHotOff);
-        addState(mWarmUp);
-        addState(mPowerOff);
-        addState(mPerProcessState);
-
-        setInitialState(mPowerOff);
-        mPublicState = BluetoothAdapter.STATE_OFF;
-        mDelayBroadcastStateOff = false;
-    }
-
-    /**
-     * Bluetooth module's power is off, firmware is not loaded.
-     */
-    private class PowerOff extends State {
-        @Override
-        public void enter() {
-            if (DBG) log("Enter PowerOff: " + getCurrentMessage().what);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            log("PowerOff process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch(message.what) {
-                case USER_TURN_ON:
-                    // starts turning on BT module, broadcast this out
-                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
-                    transitionTo(mWarmUp);
-                    if (prepareBluetooth()) {
-                        // this is user request, save the setting
-                        if ((Boolean) message.obj) {
-                            persistSwitchSetting(true);
-                        }
-                        // We will continue turn the BT on all the way to the BluetoothOn state
-                        deferMessage(obtainMessage(TURN_ON_CONTINUE));
-                    } else {
-                        Log.e(TAG, "failed to prepare bluetooth, abort turning on");
-                        transitionTo(mPowerOff);
-                        broadcastState(BluetoothAdapter.STATE_OFF);
-                    }
-                    break;
-                case TURN_HOT:
-                    if (prepareBluetooth()) {
-                        transitionTo(mWarmUp);
-                    }
-                    break;
-                case AIRPLANE_MODE_OFF:
-                    if (getBluetoothPersistedSetting()) {
-                        // starts turning on BT module, broadcast this out
-                        broadcastState(BluetoothAdapter.STATE_TURNING_ON);
-                        transitionTo(mWarmUp);
-                        if (prepareBluetooth()) {
-                            // We will continue turn the BT on all the way to the BluetoothOn state
-                            deferMessage(obtainMessage(TURN_ON_CONTINUE));
-                            transitionTo(mWarmUp);
-                        } else {
-                            Log.e(TAG, "failed to prepare bluetooth, abort turning on");
-                            transitionTo(mPowerOff);
-                            broadcastState(BluetoothAdapter.STATE_OFF);
-                        }
-                    } else if (mContext.getResources().getBoolean
-                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                        sendMessage(TURN_HOT);
-                    }
-                    break;
-                case PER_PROCESS_TURN_ON:
-                    if (prepareBluetooth()) {
-                        transitionTo(mWarmUp);
-                    }
-                    deferMessage(obtainMessage(PER_PROCESS_TURN_ON));
-                    break;
-                case PER_PROCESS_TURN_OFF:
-                    perProcessCallback(false, (IBluetoothStateChangeCallback) message.obj);
-                    break;
-                case USER_TURN_OFF:
-                    Log.w(TAG, "PowerOff received: " + message.what);
-                case AIRPLANE_MODE_ON: // ignore
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-
-        /**
-         * Turn on Bluetooth Module, Load firmware, and do all the preparation
-         * needed to get the Bluetooth Module ready but keep it not discoverable
-         * and not connectable.
-         * The last step of this method sets up the local service record DB.
-         * There will be a event reporting the status of the SDP setup.
-         */
-        private boolean prepareBluetooth() {
-            if (mBluetoothService.enableNative() != 0) {
-                return false;
-            }
-
-            // try to start event loop, give 2 attempts
-            int retryCount = 2;
-            boolean eventLoopStarted = false;
-            while ((retryCount-- > 0) && !eventLoopStarted) {
-                mEventLoop.start();
-                // it may take a moment for the other thread to do its
-                // thing.  Check periodically for a while.
-                int pollCount = 5;
-                while ((pollCount-- > 0) && !eventLoopStarted) {
-                    if (mEventLoop.isEventLoopRunning()) {
-                        eventLoopStarted = true;
-                        break;
-                    }
-                    try {
-                        Thread.sleep(100);
-                    } catch (InterruptedException e) {
-                        log("prepareBluetooth sleep interrupted: " + pollCount);
-                        break;
-                    }
-                }
-            }
-
-            if (!eventLoopStarted) {
-                mBluetoothService.disableNative();
-                return false;
-            }
-
-            // get BluetoothService ready
-            if (!mBluetoothService.prepareBluetooth()) {
-                mEventLoop.stop();
-                mBluetoothService.disableNative();
-                return false;
-            }
-
-            sendMessageDelayed(PREPARE_BLUETOOTH_TIMEOUT, PREPARE_BLUETOOTH_TIMEOUT_TIME);
-            return true;
-        }
-    }
-
-    /**
-     * Turning on Bluetooth module's power, loading firmware, starting
-     * event loop thread to listen on Bluetooth module event changes.
-     */
-    private class WarmUp extends State {
-
-        @Override
-        public void enter() {
-            if (DBG) log("Enter WarmUp: " + getCurrentMessage().what);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("WarmUp process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch(message.what) {
-                case SERVICE_RECORD_LOADED:
-                    removeMessages(PREPARE_BLUETOOTH_TIMEOUT);
-                    transitionTo(mHotOff);
-                    if (mDelayBroadcastStateOff) {
-                        broadcastState(BluetoothAdapter.STATE_OFF);
-                        mDelayBroadcastStateOff = false;
-                    }
-                    break;
-                case PREPARE_BLUETOOTH_TIMEOUT:
-                    Log.e(TAG, "Bluetooth adapter SDP failed to load");
-                    shutoffBluetooth();
-                    transitionTo(mPowerOff);
-                    broadcastState(BluetoothAdapter.STATE_OFF);
-                    break;
-                case USER_TURN_ON: // handle this at HotOff state
-                case TURN_ON_CONTINUE: // Once in HotOff state, continue turn bluetooth
-                                       // on to the BluetoothOn state
-                case AIRPLANE_MODE_ON:
-                case AIRPLANE_MODE_OFF:
-                case PER_PROCESS_TURN_ON:
-                case PER_PROCESS_TURN_OFF:
-                    deferMessage(message);
-                    break;
-                case USER_TURN_OFF:
-                    Log.w(TAG, "WarmUp received: " + message.what);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-
-    }
-
-    /**
-     * Bluetooth Module has powered, firmware loaded, event loop started,
-     * SDP loaded, but the modules stays non-discoverable and
-     * non-connectable.
-     */
-    private class HotOff extends State {
-        @Override
-        public void enter() {
-            if (DBG) log("Enter HotOff: " + getCurrentMessage().what);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("HotOff process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch(message.what) {
-                case USER_TURN_ON:
-                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
-                    if ((Boolean) message.obj) {
-                        persistSwitchSetting(true);
-                    }
-                    // let it fall to TURN_ON_CONTINUE:
-                    //$FALL-THROUGH$
-                case TURN_ON_CONTINUE:
-                    mBluetoothService.switchConnectable(true);
-                    transitionTo(mSwitching);
-                    break;
-                case AIRPLANE_MODE_ON:
-                case TURN_COLD:
-                    shutoffBluetooth();
-                    // we cannot go to power off state yet, we need wait for the Bluetooth
-                    // device power off. Unfortunately the stack does not give a event back
-                    // so we wait a little bit here
-                    sendMessageDelayed(POWER_DOWN_TIMEOUT,
-                                       POWER_DOWN_TIMEOUT_TIME);
-                    break;
-                case POWER_DOWN_TIMEOUT:
-                    transitionTo(mPowerOff);
-                    if (!mDelayBroadcastStateOff) {
-                        broadcastState(BluetoothAdapter.STATE_OFF);
-                    }
-                    break;
-                case AIRPLANE_MODE_OFF:
-                    if (getBluetoothPersistedSetting()) {
-                        broadcastState(BluetoothAdapter.STATE_TURNING_ON);
-                        transitionTo(mSwitching);
-                        mBluetoothService.switchConnectable(true);
-                    }
-                    break;
-                case PER_PROCESS_TURN_ON:
-                    transitionTo(mPerProcessState);
-
-                    // Resend the PER_PROCESS_TURN_ON message so that the callback
-                    // can be sent through.
-                    deferMessage(message);
-
-                    mBluetoothService.switchConnectable(true);
-                    break;
-                case PER_PROCESS_TURN_OFF:
-                    perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
-                    break;
-                case USER_TURN_OFF: // ignore
-                    break;
-                case POWER_STATE_CHANGED:
-                    if ((Boolean) message.obj) {
-                        recoverStateMachine(TURN_HOT, null);
-                    }
-                    break;
-                case TURN_HOT:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-
-    }
-
-    private class Switching extends State {
-
-        @Override
-        public void enter() {
-            if (DBG) log("Enter Switching: " + getCurrentMessage().what);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            log("Switching process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch(message.what) {
-                case SCAN_MODE_CHANGED:
-                    // This event matches mBluetoothService.switchConnectable action
-                    if (mPublicState == BluetoothAdapter.STATE_TURNING_ON) {
-                        // set pairable if it's not
-                        mBluetoothService.setPairable();
-                        mBluetoothService.initBluetoothAfterTurningOn();
-                        transitionTo(mBluetoothOn);
-                        broadcastState(BluetoothAdapter.STATE_ON);
-                        // run bluetooth now that it's turned on
-                        // Note runBluetooth should be called only in adapter STATE_ON
-                        mBluetoothService.runBluetooth();
-                    }
-                    break;
-                case POWER_STATE_CHANGED:
-                    removeMessages(TURN_OFF_TIMEOUT);
-                    if (!((Boolean) message.obj)) {
-                        if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) {
-                            transitionTo(mHotOff);
-                            mBluetoothService.finishDisable();
-                            mBluetoothService.cleanupAfterFinishDisable();
-                            deferMessage(obtainMessage(TURN_COLD));
-                            if (mContext.getResources().getBoolean
-                                (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch) &&
-                                !mBluetoothService.isAirplaneModeOn()) {
-                                deferMessage(obtainMessage(TURN_HOT));
-                                mDelayBroadcastStateOff = true;
-                            }
-                        }
-                    } else {
-                        if (mPublicState != BluetoothAdapter.STATE_TURNING_ON) {
-                            if (mContext.getResources().getBoolean
-                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                                recoverStateMachine(TURN_HOT, null);
-                            } else {
-                                recoverStateMachine(TURN_COLD, null);
-                            }
-                        }
-                    }
-                    break;
-                case ALL_DEVICES_DISCONNECTED:
-                    removeMessages(DEVICES_DISCONNECT_TIMEOUT);
-                    mBluetoothService.switchConnectable(false);
-                    sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
-                    break;
-                case DEVICES_DISCONNECT_TIMEOUT:
-                    sendMessage(ALL_DEVICES_DISCONNECTED);
-                    // reset the hardware for error recovery
-                    Log.e(TAG, "Devices failed to disconnect, reseting...");
-                    deferMessage(obtainMessage(TURN_COLD));
-                    if (mContext.getResources().getBoolean
-                        (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                        deferMessage(obtainMessage(TURN_HOT));
-                    }
-                    break;
-                case TURN_OFF_TIMEOUT:
-                    transitionTo(mHotOff);
-                    finishSwitchingOff();
-                    // reset the hardware for error recovery
-                    Log.e(TAG, "Devices failed to power down, reseting...");
-                    deferMessage(obtainMessage(TURN_COLD));
-                    if (mContext.getResources().getBoolean
-                        (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                        deferMessage(obtainMessage(TURN_HOT));
-                    }
-                    break;
-                case USER_TURN_ON:
-                case AIRPLANE_MODE_OFF:
-                case AIRPLANE_MODE_ON:
-                case PER_PROCESS_TURN_ON:
-                case PER_PROCESS_TURN_OFF:
-                case USER_TURN_OFF:
-                    deferMessage(message);
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-    }
-
-    private class BluetoothOn extends State {
-
-        @Override
-        public void enter() {
-            if (DBG) log("Enter BluetoothOn: " + getCurrentMessage().what);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            log("BluetoothOn process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch(message.what) {
-                case USER_TURN_OFF:
-                    if ((Boolean) message.obj) {
-                        persistSwitchSetting(false);
-                    }
-
-                    if (mBluetoothService.isDiscovering()) {
-                        mBluetoothService.cancelDiscovery();
-                    }
-                    if (!mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
-                        transitionTo(mPerProcessState);
-                        deferMessage(obtainMessage(TURN_HOT));
-                        break;
-                    }
-                    //$FALL-THROUGH$ to AIRPLANE_MODE_ON
-                case AIRPLANE_MODE_ON:
-                    broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
-                    transitionTo(mSwitching);
-                    if (mBluetoothService.getAdapterConnectionState() !=
-                        BluetoothAdapter.STATE_DISCONNECTED) {
-                        mBluetoothService.disconnectDevices();
-                        sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT,
-                                           DEVICES_DISCONNECT_TIMEOUT_TIME);
-                    } else {
-                        mBluetoothService.switchConnectable(false);
-                        sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
-                    }
-
-                    if (message.what == AIRPLANE_MODE_ON || mBluetoothService.isAirplaneModeOn()) {
-                        // We inform all the per process callbacks
-                        allProcessesCallback(false);
-                    }
-                    break;
-                case AIRPLANE_MODE_OFF:
-                case USER_TURN_ON:
-                    Log.w(TAG, "BluetoothOn received: " + message.what);
-                    break;
-                case PER_PROCESS_TURN_ON:
-                    perProcessCallback(true, (IBluetoothStateChangeCallback)message.obj);
-                    break;
-                case PER_PROCESS_TURN_OFF:
-                    perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
-                    break;
-                case POWER_STATE_CHANGED:
-                    if ((Boolean) message.obj) {
-                        // reset the state machine and send it TURN_ON_CONTINUE message
-                        recoverStateMachine(USER_TURN_ON, false);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-
-    }
-
-
-    private class PerProcessState extends State {
-        IBluetoothStateChangeCallback mCallback = null;
-        boolean isTurningOn = false;
-
-        @Override
-        public void enter() {
-            int what = getCurrentMessage().what;
-            if (DBG) log("Enter PerProcessState: " + what);
-
-            if (what == PER_PROCESS_TURN_ON) {
-                isTurningOn = true;
-            } else if (what == USER_TURN_OFF) {
-                isTurningOn = false;
-            } else {
-                Log.e(TAG, "enter PerProcessState: wrong msg: " + what);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            log("PerProcessState process message: " + message.what);
-
-            boolean retValue = HANDLED;
-            switch (message.what) {
-                case PER_PROCESS_TURN_ON:
-                    mCallback = (IBluetoothStateChangeCallback)getCurrentMessage().obj;
-
-                    // If this is not the first application call the callback.
-                    if (mBluetoothService.getNumberOfApplicationStateChangeTrackers() > 1) {
-                        perProcessCallback(true, mCallback);
-                    }
-                    break;
-                case SCAN_MODE_CHANGED:
-                    if (isTurningOn) {
-                        perProcessCallback(true, mCallback);
-                        isTurningOn = false;
-                    }
-                    break;
-                case POWER_STATE_CHANGED:
-                    removeMessages(TURN_OFF_TIMEOUT);
-                    if (!((Boolean) message.obj)) {
-                        transitionTo(mHotOff);
-                        if (!mContext.getResources().getBoolean
-                            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                            deferMessage(obtainMessage(TURN_COLD));
-                        }
-                    } else {
-                        if (!isTurningOn) {
-                            recoverStateMachine(TURN_COLD, null);
-                            for (IBluetoothStateChangeCallback c:
-                                     mBluetoothService.getApplicationStateChangeCallbacks()) {
-                                perProcessCallback(false, c);
-                                deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c));
-                            }
-                        }
-                    }
-                    break;
-                case TURN_OFF_TIMEOUT:
-                    transitionTo(mHotOff);
-                    Log.e(TAG, "Power-down timed out, resetting...");
-                    deferMessage(obtainMessage(TURN_COLD));
-                    if (mContext.getResources().getBoolean
-                        (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-                        deferMessage(obtainMessage(TURN_HOT));
-                    }
-                    break;
-                case USER_TURN_ON:
-                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
-                    persistSwitchSetting(true);
-                    mBluetoothService.initBluetoothAfterTurningOn();
-                    transitionTo(mBluetoothOn);
-                    broadcastState(BluetoothAdapter.STATE_ON);
-                    // run bluetooth now that it's turned on
-                    mBluetoothService.runBluetooth();
-                    break;
-                case TURN_HOT:
-                    broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
-                    if (mBluetoothService.getAdapterConnectionState() !=
-                        BluetoothAdapter.STATE_DISCONNECTED) {
-                        mBluetoothService.disconnectDevices();
-                        sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT,
-                                           DEVICES_DISCONNECT_TIMEOUT_TIME);
-                        break;
-                    }
-                    //$FALL-THROUGH$ all devices are already disconnected
-                case ALL_DEVICES_DISCONNECTED:
-                    removeMessages(DEVICES_DISCONNECT_TIMEOUT);
-                    finishSwitchingOff();
-                    break;
-                case DEVICES_DISCONNECT_TIMEOUT:
-                    finishSwitchingOff();
-                    Log.e(TAG, "Devices fail to disconnect, reseting...");
-                    transitionTo(mHotOff);
-                    deferMessage(obtainMessage(TURN_COLD));
-                    for (IBluetoothStateChangeCallback c:
-                             mBluetoothService.getApplicationStateChangeCallbacks()) {
-                        perProcessCallback(false, c);
-                        deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c));
-                    }
-                    break;
-                case PER_PROCESS_TURN_OFF:
-                    perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
-                    if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
-                        mBluetoothService.switchConnectable(false);
-                        sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
-                    }
-                    break;
-                case AIRPLANE_MODE_ON:
-                    mBluetoothService.switchConnectable(false);
-                    sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
-                    allProcessesCallback(false);
-                    break;
-                case USER_TURN_OFF:
-                    Log.w(TAG, "PerProcessState received: " + message.what);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return retValue;
-        }
-    }
-
-    private void finishSwitchingOff() {
-        mBluetoothService.finishDisable();
-        broadcastState(BluetoothAdapter.STATE_OFF);
-        mBluetoothService.cleanupAfterFinishDisable();
-    }
-
-    private void shutoffBluetooth() {
-        mBluetoothService.shutoffBluetooth();
-        mEventLoop.stop();
-        mBluetoothService.cleanNativeAfterShutoffBluetooth();
-    }
-
-    private void perProcessCallback(boolean on, IBluetoothStateChangeCallback c) {
-        if (c == null) return;
-
-        try {
-            c.onBluetoothStateChange(on);
-        } catch (RemoteException e) {}
-    }
-
-    private void allProcessesCallback(boolean on) {
-        for (IBluetoothStateChangeCallback c:
-             mBluetoothService.getApplicationStateChangeCallbacks()) {
-            perProcessCallback(on, c);
-        }
-        if (!on) {
-            mBluetoothService.clearApplicationStateChangeTracker();
-        }
-    }
-
-    /**
-     * Return the public BluetoothAdapter state
-     */
-    int getBluetoothAdapterState() {
-        return mPublicState;
-    }
-
-    BluetoothEventLoop getBluetoothEventLoop() {
-        return mEventLoop;
-    }
-
-    private void persistSwitchSetting(boolean setOn) {
-        long origCallerIdentityToken = Binder.clearCallingIdentity();
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                               Settings.Secure.BLUETOOTH_ON,
-                               setOn ? 1 : 0);
-        Binder.restoreCallingIdentity(origCallerIdentityToken);
-    }
-
-    private boolean getBluetoothPersistedSetting() {
-        ContentResolver contentResolver = mContext.getContentResolver();
-        return (Settings.Secure.getInt(contentResolver,
-                                       Settings.Secure.BLUETOOTH_ON, 0) > 0);
-    }
-
-    private void broadcastState(int newState) {
-
-        log("Bluetooth state " + mPublicState + " -> " + newState);
-        if (mPublicState == newState) {
-            return;
-        }
-
-        Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
-        intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, mPublicState);
-        intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mPublicState = newState;
-
-        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
-    }
-
-    /**
-     * bluetoothd has crashed and recovered, the adapter state machine has to
-     * reset itself and try to return to previous state
-     */
-    private void recoverStateMachine(int what, Object obj) {
-        Log.e(TAG, "Get unexpected power on event, reset with: " + what);
-        transitionTo(mHotOff);
-        deferMessage(obtainMessage(TURN_COLD));
-        deferMessage(obtainMessage(what, obj));
-    }
-
-    private void dump(PrintWriter pw) {
-        IState currentState = getCurrentState();
-        if (currentState == mPowerOff) {
-            pw.println("Bluetooth OFF - power down\n");
-        } else if (currentState == mWarmUp) {
-            pw.println("Bluetooth OFF - warm up\n");
-        } else if (currentState == mHotOff) {
-            pw.println("Bluetooth OFF - hot but off\n");
-        } else if (currentState == mSwitching) {
-            pw.println("Bluetooth Switching\n");
-        } else if (currentState == mBluetoothOn) {
-            pw.println("Bluetooth ON\n");
-        } else {
-            pw.println("ERROR: Bluetooth UNKNOWN STATE ");
-        }
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/core/java/android/server/BluetoothBondState.java b/core/java/android/server/BluetoothBondState.java
deleted file mode 100644
index 0446f02..0000000
--- a/core/java/android/server/BluetoothBondState.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothHeadset;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Local cache of bonding state.
- * We keep our own state to track the intermediate state BONDING, which
- * bluez does not track.
- * All addresses must be passed in upper case.
- */
-class BluetoothBondState {
-    private static final String TAG = "BluetoothBondState";
-    private static final boolean DBG =  true;
-
-    private final HashMap<String, Integer> mState = new HashMap<String, Integer>();
-    private final HashMap<String, Integer> mPinAttempt = new HashMap<String, Integer>();
-
-    private static final String AUTO_PAIRING_BLACKLIST =
-        "/etc/bluetooth/auto_pairing.conf";
-    private static final String DYNAMIC_AUTO_PAIRING_BLACKLIST =
-        "/data/misc/bluetooth/dynamic_auto_pairing.conf";
-    private ArrayList<String> mAutoPairingAddressBlacklist;
-    private ArrayList<String> mAutoPairingExactNameBlacklist;
-    private ArrayList<String> mAutoPairingPartialNameBlacklist;
-    private ArrayList<String> mAutoPairingFixedPinZerosKeyboardList;
-    // Addresses added to blacklist dynamically based on usage.
-    private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
-
-    // If this is an outgoing connection, store the address.
-    // There can be only 1 pending outgoing connection at a time,
-    private String mPendingOutgoingBonding;
-
-    private final Context mContext;
-    private final BluetoothService mService;
-    private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
-    private BluetoothA2dp mA2dpProxy;
-    private BluetoothHeadset mHeadsetProxy;
-
-    private ArrayList<String> mPairingRequestRcvd = new ArrayList<String>();
-
-    BluetoothBondState(Context context, BluetoothService service) {
-        mContext = context;
-        mService = service;
-        mBluetoothInputProfileHandler =
-            BluetoothInputProfileHandler.getInstance(mContext, mService);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        mContext.registerReceiver(mReceiver, filter);
-        readAutoPairingData();
-    }
-
-    synchronized void setPendingOutgoingBonding(String address) {
-        mPendingOutgoingBonding = address;
-    }
-
-    public synchronized String getPendingOutgoingBonding() {
-        return mPendingOutgoingBonding;
-    }
-
-    public synchronized void initBondState() {
-        getProfileProxy();
-        loadBondState();
-    }
-
-    private void loadBondState() {
-        if (mService.getBluetoothStateInternal() !=
-                BluetoothAdapter.STATE_TURNING_ON) {
-            return;
-        }
-        String val = mService.getAdapterProperties().getProperty("Devices");
-        if (val == null) {
-            return;
-        }
-        String[] bonds = val.split(",");
-        if (bonds == null) {
-            return;
-        }
-        mState.clear();
-        if (DBG) Log.d(TAG, "found " + bonds.length + " bonded devices");
-        for (String device : bonds) {
-            mState.put(mService.getAddressFromObjectPath(device).toUpperCase(),
-                    BluetoothDevice.BOND_BONDED);
-        }
-    }
-
-    public synchronized void setBondState(String address, int state) {
-        setBondState(address, state, 0);
-    }
-
-    /** reason is ignored unless state == BOND_NOT_BONDED */
-    public synchronized void setBondState(String address, int state, int reason) {
-        if (DBG) Log.d(TAG, "setBondState " + "address" + " " + state + "reason: " + reason);
-
-        int oldState = getBondState(address);
-        if (oldState == state) {
-            return;
-        }
-
-        // Check if this was a pending outgoing bonding.
-        // If yes, reset the state.
-        if (oldState == BluetoothDevice.BOND_BONDING) {
-            if (address.equals(mPendingOutgoingBonding)) {
-                mPendingOutgoingBonding = null;
-            }
-        }
-
-        if (state == BluetoothDevice.BOND_BONDED) {
-            boolean setTrust = false;
-            if (mPairingRequestRcvd.contains(address)) setTrust = true;
-
-            mService.addProfileState(address, setTrust);
-            mPairingRequestRcvd.remove(address);
-
-        } else if (state == BluetoothDevice.BOND_BONDING) {
-            if (mA2dpProxy == null || mHeadsetProxy == null) {
-                getProfileProxy();
-            }
-        } else if (state == BluetoothDevice.BOND_NONE) {
-            mPairingRequestRcvd.remove(address);
-        }
-
-        setProfilePriorities(address, state);
-
-        if (DBG) {
-            Log.d(TAG, address + " bond state " + oldState + " -> " + state
-                + " (" + reason + ")");
-        }
-        Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mService.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state);
-        intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
-        if (state == BluetoothDevice.BOND_NONE) {
-            if (reason <= 0) {
-                Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
-                      "invalid. Overriding reason code with BOND_RESULT_REMOVED");
-                reason = BluetoothDevice.UNBOND_REASON_REMOVED;
-            }
-            intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
-            mState.remove(address);
-        } else {
-            mState.put(address, state);
-        }
-
-        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
-    }
-
-    public boolean isAutoPairingBlacklisted(String address) {
-        if (mAutoPairingAddressBlacklist != null) {
-            for (String blacklistAddress : mAutoPairingAddressBlacklist) {
-                if (address.startsWith(blacklistAddress)) return true;
-            }
-        }
-
-        if (mAutoPairingDynamicAddressBlacklist != null) {
-            for (String blacklistAddress: mAutoPairingDynamicAddressBlacklist) {
-                if (address.equals(blacklistAddress)) return true;
-            }
-        }
-
-        String name = mService.getRemoteName(address);
-        if (name != null) {
-            if (mAutoPairingExactNameBlacklist != null) {
-                for (String blacklistName : mAutoPairingExactNameBlacklist) {
-                    if (name.equals(blacklistName)) return true;
-                }
-            }
-
-            if (mAutoPairingPartialNameBlacklist != null) {
-                for (String blacklistName : mAutoPairingPartialNameBlacklist) {
-                    if (name.startsWith(blacklistName)) return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public boolean isFixedPinZerosAutoPairKeyboard(String address) {
-        // Note: the meaning of blacklist is reversed in this case.
-        // If its in the list, we can go ahead and auto pair since
-        // by default keyboard should have a variable PIN that we don't
-        // auto pair using 0000.
-        if (mAutoPairingFixedPinZerosKeyboardList != null) {
-            for (String blacklistAddress : mAutoPairingFixedPinZerosKeyboardList) {
-                if (address.startsWith(blacklistAddress)) return true;
-            }
-        }
-        return false;
-    }
-
-    public synchronized int getBondState(String address) {
-        Integer state = mState.get(address);
-        if (state == null) {
-            return BluetoothDevice.BOND_NONE;
-        }
-        return state.intValue();
-    }
-
-    /*package*/ synchronized String[] listInState(int state) {
-        ArrayList<String> result = new ArrayList<String>(mState.size());
-        for (Map.Entry<String, Integer> e : mState.entrySet()) {
-            if (e.getValue().intValue() == state) {
-                result.add(e.getKey());
-            }
-        }
-        return result.toArray(new String[result.size()]);
-    }
-
-    public synchronized void addAutoPairingFailure(String address) {
-        if (mAutoPairingDynamicAddressBlacklist == null) {
-            mAutoPairingDynamicAddressBlacklist = new ArrayList<String>();
-        }
-
-        updateAutoPairingData(address);
-        mAutoPairingDynamicAddressBlacklist.add(address);
-    }
-
-    public synchronized boolean isAutoPairingAttemptsInProgress(String address) {
-        return getAttempt(address) != 0;
-    }
-
-    public synchronized void clearPinAttempts(String address) {
-        if (DBG) Log.d(TAG, "clearPinAttempts: " + address);
-
-        mPinAttempt.remove(address);
-    }
-
-    public synchronized boolean hasAutoPairingFailed(String address) {
-        if (mAutoPairingDynamicAddressBlacklist == null) return false;
-
-        return mAutoPairingDynamicAddressBlacklist.contains(address);
-    }
-
-    public synchronized int getAttempt(String address) {
-        Integer attempt = mPinAttempt.get(address);
-        if (attempt == null) {
-            return 0;
-        }
-        return attempt.intValue();
-    }
-
-    public synchronized void attempt(String address) {
-        Integer attempt = mPinAttempt.get(address);
-        int newAttempt;
-        if (attempt == null) {
-            newAttempt = 1;
-        } else {
-            newAttempt = attempt.intValue() + 1;
-        }
-        if (DBG) Log.d(TAG, "attemp newAttempt: " + newAttempt);
-
-        mPinAttempt.put(address, new Integer(newAttempt));
-    }
-
-    private void getProfileProxy() {
-        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        if (mA2dpProxy == null) {
-            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
-                                             BluetoothProfile.A2DP);
-        }
-
-        if (mHeadsetProxy == null) {
-            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
-                                             BluetoothProfile.HEADSET);
-        }
-    }
-
-    private void closeProfileProxy() {
-        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
-        if (mA2dpProxy != null) {
-            bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mA2dpProxy);
-        }
-
-        if (mHeadsetProxy != null) {
-            bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetProxy);
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mProfileServiceListener =
-        new BluetoothProfile.ServiceListener() {
-
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.A2DP) {
-                mA2dpProxy = (BluetoothA2dp) proxy;
-            } else if (profile == BluetoothProfile.HEADSET) {
-                mHeadsetProxy = (BluetoothHeadset) proxy;
-            }
-        }
-
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.A2DP) {
-                mA2dpProxy = null;
-            } else if (profile == BluetoothProfile.HEADSET) {
-                mHeadsetProxy = null;
-            }
-        }
-    };
-
-    private void copyAutoPairingData() {
-        FileInputStream in = null;
-        FileOutputStream out = null;
-        try {
-            File file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-            if (file.exists()) return;
-
-            in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
-            out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-
-            byte[] buf = new byte[1024];
-            int len;
-            while ((len = in.read(buf)) > 0) {
-                out.write(buf, 0, len);
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "FileNotFoundException: copyAutoPairingData " + e);
-        } catch (IOException e) {
-            Log.e(TAG, "IOException: copyAutoPairingData " + e);
-        } finally {
-             try {
-                 if (in != null) in.close();
-                 if (out != null) out.close();
-             } catch (IOException e) {}
-        }
-    }
-
-    synchronized public void readAutoPairingData() {
-        if (mAutoPairingAddressBlacklist != null) return;
-        copyAutoPairingData();
-        FileInputStream fstream = null;
-        try {
-            fstream = new FileInputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-            DataInputStream in = new DataInputStream(fstream);
-            BufferedReader file = new BufferedReader(new InputStreamReader(in));
-            String line;
-            while((line = file.readLine()) != null) {
-                line = line.trim();
-                if (line.length() == 0 || line.startsWith("//")) continue;
-                String[] value = line.split("=");
-                if (value != null && value.length == 2) {
-                    String[] val = value[1].split(",");
-                    if (value[0].equalsIgnoreCase("AddressBlacklist")) {
-                        mAutoPairingAddressBlacklist =
-                            new ArrayList<String>(Arrays.asList(val));
-                    } else if (value[0].equalsIgnoreCase("ExactNameBlacklist")) {
-                        mAutoPairingExactNameBlacklist =
-                            new ArrayList<String>(Arrays.asList(val));
-                    } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
-                        mAutoPairingPartialNameBlacklist =
-                            new ArrayList<String>(Arrays.asList(val));
-                    } else if (value[0].equalsIgnoreCase("FixedPinZerosKeyboardBlacklist")) {
-                        mAutoPairingFixedPinZerosKeyboardList =
-                            new ArrayList<String>(Arrays.asList(val));
-                    } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
-                        mAutoPairingDynamicAddressBlacklist =
-                            new ArrayList<String>(Arrays.asList(val));
-                    } else {
-                        Log.e(TAG, "Error parsing Auto pairing blacklist file");
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "FileNotFoundException: readAutoPairingData " + e);
-        } catch (IOException e) {
-            Log.e(TAG, "IOException: readAutoPairingData " + e);
-        } finally {
-            if (fstream != null) {
-                try {
-                    fstream.close();
-                } catch (IOException e) {
-                    // Ignore
-                }
-            }
-        }
-    }
-
-    // This function adds a bluetooth address to the auto pairing blacklist
-    // file. These addresses are added to DynamicAddressBlacklistSection
-    private void updateAutoPairingData(String address) {
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new FileWriter(DYNAMIC_AUTO_PAIRING_BLACKLIST, true));
-            StringBuilder str = new StringBuilder();
-            if (mAutoPairingDynamicAddressBlacklist.size() == 0) {
-                str.append("DynamicAddressBlacklist=");
-            }
-            str.append(address);
-            str.append(",");
-            out.write(str.toString());
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "FileNotFoundException: updateAutoPairingData " + e);
-        } catch (IOException e) {
-            Log.e(TAG, "IOException: updateAutoPairingData " + e);
-        } finally {
-            if (out != null) {
-                try {
-                    out.close();
-                } catch (IOException e) {
-                    // Ignore
-                }
-            }
-        }
-    }
-
-    // Set service priority of Hid, A2DP and Headset profiles depending on
-    // the bond state change
-    private void setProfilePriorities(String address, int state) {
-        BluetoothDevice remoteDevice = mService.getRemoteDevice(address);
-        // HID is handled by BluetoothService
-        mBluetoothInputProfileHandler.setInitialInputDevicePriority(remoteDevice, state);
-
-        // Set service priority of A2DP and Headset
-        // We used to do the priority change in the 2 services after the broadcast
-        //   intent reach them. But that left a small time gap that could reject
-        //   incoming connection due to undefined priorities.
-        if (state == BluetoothDevice.BOND_BONDED) {
-            if (mA2dpProxy != null &&
-                  mA2dpProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
-                mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
-            }
-
-            if (mHeadsetProxy != null &&
-                  mHeadsetProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
-                mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
-            }
-        } else if (state == BluetoothDevice.BOND_NONE) {
-            if (mA2dpProxy != null) {
-                mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
-            }
-            if (mHeadsetProxy != null) {
-                mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
-            }
-        }
-
-        if (mA2dpProxy == null || mHeadsetProxy == null) {
-            Log.e(TAG, "Proxy is null:" + mA2dpProxy + ":" + mHeadsetProxy);
-        }
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent == null) return;
-
-            String action = intent.getAction();
-            if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
-                BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                String address = dev.getAddress();
-                mPairingRequestRcvd.add(address);
-            }
-        }
-    };
-}
diff --git a/core/java/android/server/BluetoothDeviceProperties.java b/core/java/android/server/BluetoothDeviceProperties.java
deleted file mode 100644
index fe3ef79..0000000
--- a/core/java/android/server/BluetoothDeviceProperties.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.os.ParcelUuid;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-class BluetoothDeviceProperties {
-
-    private static final String TAG = "BluetoothDeviceProperties";
-
-    private final HashMap<String, Map<String, String>> mPropertiesMap;
-    private final BluetoothService mService;
-
-    BluetoothDeviceProperties(BluetoothService service) {
-        mPropertiesMap = new HashMap<String, Map<String, String>>();
-        mService = service;
-    }
-
-    Map<String, String> addProperties(String address, String[] properties) {
-        /*
-         * We get a DeviceFound signal every time RSSI changes or name changes.
-         * Don't create a new Map object every time.
-         */
-        Map<String, String> propertyValues;
-        synchronized(mPropertiesMap) {
-            propertyValues = mPropertiesMap.get(address);
-            if (propertyValues == null) {
-                propertyValues = new HashMap<String, String>();
-            }
-
-            for (int i = 0; i < properties.length; i++) {
-                String name = properties[i];
-                String newValue = null;
-                int len;
-                if (name == null) {
-                    Log.e(TAG, "Error: Remote Device Property at index "
-                        + i + " is null");
-                    continue;
-                }
-                if (name.equals("UUIDs") || name.equals("Nodes")) {
-                    StringBuilder str = new StringBuilder();
-                    len = Integer.valueOf(properties[++i]);
-                    for (int j = 0; j < len; j++) {
-                        str.append(properties[++i]);
-                        str.append(",");
-                    }
-                    if (len > 0) {
-                        newValue = str.toString();
-                    }
-                } else {
-                    newValue = properties[++i];
-                }
-
-                propertyValues.put(name, newValue);
-            }
-            mPropertiesMap.put(address, propertyValues);
-        }
-
-        // We have added a new remote device or updated its properties.
-        // Also update the serviceChannel cache.
-        mService.updateDeviceServiceChannelCache(address);
-        return propertyValues;
-    }
-
-    void setProperty(String address, String name, String value) {
-        synchronized(mPropertiesMap) {
-            Map <String, String> propVal = mPropertiesMap.get(address);
-            if (propVal != null) {
-                propVal.put(name, value);
-                mPropertiesMap.put(address, propVal);
-            } else {
-                Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address);
-            }
-        }
-    }
-
-    boolean isInCache(String address) {
-        synchronized (mPropertiesMap) {
-            return (mPropertiesMap.get(address) != null);
-        }
-    }
-
-    boolean isEmpty() {
-        synchronized (mPropertiesMap) {
-            return mPropertiesMap.isEmpty();
-        }
-    }
-
-    Set<String> keySet() {
-        synchronized (mPropertiesMap) {
-            return mPropertiesMap.keySet();
-        }
-    }
-
-    String getProperty(String address, String property) {
-        synchronized(mPropertiesMap) {
-            Map<String, String> properties = mPropertiesMap.get(address);
-            if (properties != null) {
-                return properties.get(property);
-            } else {
-                // Query for remote device properties, again.
-                // We will need to reload the cache when we switch Bluetooth on / off
-                // or if we crash.
-                properties = updateCache(address);
-                if (properties != null) {
-                    return properties.get(property);
-                }
-            }
-        }
-        Log.e(TAG, "getRemoteDeviceProperty: " + property + " not present: " + address);
-        return null;
-    }
-
-    Map<String, String> updateCache(String address) {
-        String[] propValues = mService.getRemoteDeviceProperties(address);
-        if (propValues != null) {
-            return addProperties(address, propValues);
-        }
-        return null;
-    }
-}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
deleted file mode 100644
index b758e7fa..0000000
--- a/core/java/android/server/BluetoothEventLoop.java
+++ /dev/null
@@ -1,1067 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHealth;
-import android.bluetooth.BluetoothInputDevice;
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothUuid;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelUuid;
-import android.os.PowerManager;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-
-/**
- * @hide
- */
-class BluetoothEventLoop {
-    private static final String TAG = "BluetoothEventLoop";
-    private static final boolean DBG = false;
-
-    private int mNativeData;
-    private Thread mThread;
-    private boolean mStarted;
-    private boolean mInterrupted;
-
-    private final HashMap<String, Integer> mPasskeyAgentRequestData;
-    private final HashMap<String, Integer> mAuthorizationAgentRequestData;
-    private final BluetoothService mBluetoothService;
-    private final BluetoothAdapter mAdapter;
-    private final BluetoothAdapterStateMachine mBluetoothState;
-    private BluetoothA2dp mA2dp;
-    private final Context mContext;
-    // The WakeLock is used for bringing up the LCD during a pairing request
-    // from remote device when Android is in Suspend state.
-    private PowerManager.WakeLock mWakeLock;
-
-    private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 1;
-    private static final int EVENT_AGENT_CANCEL = 2;
-
-    private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
-    private static final int CREATE_DEVICE_SUCCESS = 0;
-    private static final int CREATE_DEVICE_FAILED = -1;
-
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            String address = null;
-            switch (msg.what) {
-            case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
-                address = (String)msg.obj;
-                if (address != null) {
-                    mBluetoothService.setPairingConfirmation(address, true);
-                }
-                break;
-            case EVENT_AGENT_CANCEL:
-                // Set the Bond State to BOND_NONE.
-                // We always have only 1 device in BONDING state.
-                String[] devices = mBluetoothService.listInState(BluetoothDevice.BOND_BONDING);
-                if (devices.length == 0) {
-                    break;
-                } else if (devices.length > 1) {
-                    Log.e(TAG, " There is more than one device in the Bonding State");
-                    break;
-                }
-                address = devices[0];
-                mBluetoothService.setBondState(address,
-                        BluetoothDevice.BOND_NONE,
-                        BluetoothDevice.UNBOND_REASON_REMOTE_AUTH_CANCELED);
-                break;
-            }
-        }
-    };
-
-    static { classInitNative(); }
-    private static native void classInitNative();
-
-    /* package */ BluetoothEventLoop(Context context, BluetoothAdapter adapter,
-                                     BluetoothService bluetoothService,
-                                     BluetoothAdapterStateMachine bluetoothState) {
-        mBluetoothService = bluetoothService;
-        mContext = context;
-        mBluetoothState = bluetoothState;
-        mPasskeyAgentRequestData = new HashMap<String, Integer>();
-        mAuthorizationAgentRequestData = new HashMap<String, Integer>();
-        mAdapter = adapter;
-        //WakeLock instantiation in BluetoothEventLoop class
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
-                | PowerManager.ON_AFTER_RELEASE, TAG);
-        mWakeLock.setReferenceCounted(false);
-        initializeNativeDataNative();
-    }
-
-    /*package*/ void getProfileProxy() {
-        mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
-        mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
-    }
-
-    private BluetoothProfile.ServiceListener mProfileServiceListener =
-        new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.A2DP) {
-                mA2dp = (BluetoothA2dp) proxy;
-            }
-        }
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.A2DP) {
-                mA2dp = null;
-            }
-        }
-    };
-
-
-    protected void finalize() throws Throwable {
-        try {
-            cleanupNativeDataNative();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    /* package */ HashMap<String, Integer> getPasskeyAgentRequestData() {
-        return mPasskeyAgentRequestData;
-    }
-
-    /* package */ HashMap<String, Integer> getAuthorizationAgentRequestData() {
-        return mAuthorizationAgentRequestData;
-    }
-
-    /* package */ void start() {
-
-        if (!isEventLoopRunningNative()) {
-            if (DBG) log("Starting Event Loop thread");
-            startEventLoopNative();
-        }
-    }
-
-    public void stop() {
-        if (isEventLoopRunningNative()) {
-            if (DBG) log("Stopping Event Loop thread");
-            stopEventLoopNative();
-        }
-    }
-
-    public boolean isEventLoopRunning() {
-        return isEventLoopRunningNative();
-    }
-
-    private void addDevice(String address, String[] properties) {
-        BluetoothDeviceProperties deviceProperties =
-                mBluetoothService.getDeviceProperties();
-        deviceProperties.addProperties(address, properties);
-        String rssi = deviceProperties.getProperty(address, "RSSI");
-        String classValue = deviceProperties.getProperty(address, "Class");
-        String name = deviceProperties.getProperty(address, "Name");
-        short rssiValue;
-        // For incoming connections, we don't get the RSSI value. Use a default of MIN_VALUE.
-        // If we accept the pairing, we will automatically show it at the top of the list.
-        if (rssi != null) {
-            rssiValue = (short)Integer.valueOf(rssi).intValue();
-        } else {
-            rssiValue = Short.MIN_VALUE;
-        }
-        if (classValue != null) {
-            Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-            intent.putExtra(BluetoothDevice.EXTRA_CLASS,
-                    new BluetoothClass(Integer.valueOf(classValue)));
-            intent.putExtra(BluetoothDevice.EXTRA_RSSI, rssiValue);
-            intent.putExtra(BluetoothDevice.EXTRA_NAME, name);
-
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else {
-            log ("ClassValue: " + classValue + " for remote device: " + address + " is null");
-        }
-    }
-
-    /**
-     * Called by native code on a DeviceFound signal from org.bluez.Adapter.
-     *
-     * @param address the MAC address of the new device
-     * @param properties an array of property keys and value strings
-     *
-     * @see BluetoothDeviceProperties#addProperties(String, String[])
-     */
-    private void onDeviceFound(String address, String[] properties) {
-        if (properties == null) {
-            Log.e(TAG, "ERROR: Remote device properties are null");
-            return;
-        }
-        addDevice(address, properties);
-    }
-
-    /**
-     * Called by native code on a DeviceDisappeared signal from
-     * org.bluez.Adapter.
-     *
-     * @param address the MAC address of the disappeared device
-     */
-    private void onDeviceDisappeared(String address) {
-        Intent intent = new Intent(BluetoothDevice.ACTION_DISAPPEARED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-    }
-
-    /**
-     * Called by native code on a DisconnectRequested signal from
-     * org.bluez.Device.
-     *
-     * @param deviceObjectPath the object path for the disconnecting device
-     */
-    private void onDeviceDisconnectRequested(String deviceObjectPath) {
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address == null) {
-            Log.e(TAG, "onDeviceDisconnectRequested: Address of the remote device in null");
-            return;
-        }
-        Intent intent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-    }
-
-    /**
-     * Called by native code for the async response to a CreatePairedDevice
-     * method call to org.bluez.Adapter.
-     *
-     * @param address the MAC address of the device to pair
-     * @param result success or error result for the pairing operation
-     */
-    private void onCreatePairedDeviceResult(String address, int result) {
-        address = address.toUpperCase();
-        mBluetoothService.onCreatePairedDeviceResult(address, result);
-    }
-
-    /**
-     * Called by native code on a DeviceCreated signal from org.bluez.Adapter.
-     *
-     * @param deviceObjectPath the object path for the created device
-     */
-    private void onDeviceCreated(String deviceObjectPath) {
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address == null) {
-            Log.e(TAG, "onDeviceCreated: device address null!" + " deviceObjectPath: " +
-                  deviceObjectPath);
-            return;
-        }
-        if (!mBluetoothService.isRemoteDeviceInCache(address)) {
-            // Incoming connection, we haven't seen this device, add to cache.
-            String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
-            if (properties != null) {
-                addDevice(address, properties);
-            }
-        }
-    }
-
-    /**
-     * Called by native code on a DeviceRemoved signal from org.bluez.Adapter.
-     *
-     * @param deviceObjectPath the object path for the removed device
-     */
-    private void onDeviceRemoved(String deviceObjectPath) {
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address != null) {
-            mBluetoothService.setBondState(address.toUpperCase(), BluetoothDevice.BOND_NONE,
-                BluetoothDevice.UNBOND_REASON_REMOVED);
-            mBluetoothService.setRemoteDeviceProperty(address, "UUIDs", null);
-        }
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.Adapter. This method is also called from
-     * {@link BluetoothAdapterStateMachine} to set the "Pairable"
-     * property when Bluetooth is enabled.
-     *
-     * @param propValues a string array containing the key and one or more
-     *  values.
-     */
-    /*package*/ void onPropertyChanged(String[] propValues) {
-        BluetoothAdapterProperties adapterProperties =
-                mBluetoothService.getAdapterProperties();
-
-        if (adapterProperties.isEmpty()) {
-            // We have got a property change before
-            // we filled up our cache.
-            adapterProperties.getAllProperties();
-        }
-        log("Property Changed: " + propValues[0] + " : " + propValues[1]);
-        String name = propValues[0];
-        if (name.equals("Name")) {
-            adapterProperties.setProperty(name, propValues[1]);
-            Intent intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
-            intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, propValues[1]);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Pairable") || name.equals("Discoverable")) {
-            adapterProperties.setProperty(name, propValues[1]);
-
-            if (name.equals("Discoverable")) {
-                mBluetoothState.sendMessage(BluetoothAdapterStateMachine.SCAN_MODE_CHANGED);
-            }
-
-            String pairable = name.equals("Pairable") ? propValues[1] :
-                adapterProperties.getProperty("Pairable");
-            String discoverable = name.equals("Discoverable") ? propValues[1] :
-                adapterProperties.getProperty("Discoverable");
-
-            // This shouldn't happen, unless Adapter Properties are null.
-            if (pairable == null || discoverable == null)
-                return;
-
-            int mode = BluetoothService.bluezStringToScanMode(
-                    pairable.equals("true"),
-                    discoverable.equals("true"));
-            if (mode >= 0) {
-                Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-                intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mode);
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-                mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-            }
-        } else if (name.equals("Discovering")) {
-            Intent intent;
-            adapterProperties.setProperty(name, propValues[1]);
-            if (propValues[1].equals("true")) {
-                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
-            } else {
-                // Stop the discovery.
-                mBluetoothService.cancelDiscovery();
-                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
-            }
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Devices") || name.equals("UUIDs")) {
-            String value = null;
-            int len = Integer.valueOf(propValues[1]);
-            if (len > 0) {
-                StringBuilder str = new StringBuilder();
-                for (int i = 2; i < propValues.length; i++) {
-                    str.append(propValues[i]);
-                    str.append(",");
-                }
-                value = str.toString();
-            }
-            adapterProperties.setProperty(name, value);
-            if (name.equals("UUIDs")) {
-                mBluetoothService.updateBluetoothState(value);
-            }
-        } else if (name.equals("Powered")) {
-            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.POWER_STATE_CHANGED,
-                propValues[1].equals("true") ? new Boolean(true) : new Boolean(false));
-        } else if (name.equals("DiscoverableTimeout")) {
-            adapterProperties.setProperty(name, propValues[1]);
-        }
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.Device.
-     *
-     * @param deviceObjectPath the object path for the changed device
-     * @param propValues a string array containing the key and one or more
-     *  values.
-     */
-    private void onDevicePropertyChanged(String deviceObjectPath, String[] propValues) {
-        String name = propValues[0];
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address == null) {
-            Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
-            return;
-        }
-        log("Device property changed: " + address + " property: "
-            + name + " value: " + propValues[1]);
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        if (name.equals("Name")) {
-            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
-            Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Alias")) {
-            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
-            Intent intent = new Intent(BluetoothDevice.ACTION_ALIAS_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Class")) {
-            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
-            Intent intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.putExtra(BluetoothDevice.EXTRA_CLASS,
-                    new BluetoothClass(Integer.valueOf(propValues[1])));
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("Connected")) {
-            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
-            Intent intent = null;
-            if (propValues[1].equals("true")) {
-                intent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED);
-                // Set the link timeout to 8000 slots (5 sec timeout)
-                // for bluetooth docks.
-                if (mBluetoothService.isBluetoothDock(address)) {
-                    mBluetoothService.setLinkTimeout(address, 8000);
-                }
-            } else {
-                intent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECTED);
-            }
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else if (name.equals("UUIDs")) {
-            String uuid = null;
-            int len = Integer.valueOf(propValues[1]);
-            if (len > 0) {
-                StringBuilder str = new StringBuilder();
-                for (int i = 2; i < propValues.length; i++) {
-                    str.append(propValues[i]);
-                    str.append(",");
-                }
-                uuid = str.toString();
-            }
-            mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
-
-            // UUIDs have changed, query remote service channel and update cache.
-            mBluetoothService.updateDeviceServiceChannelCache(address);
-
-            mBluetoothService.sendUuidIntent(address);
-        } else if (name.equals("Paired")) {
-            if (propValues[1].equals("true")) {
-                // If locally initiated pairing, we will
-                // not go to BOND_BONDED state until we have received a
-                // successful return value in onCreatePairedDeviceResult
-                if (null == mBluetoothService.getPendingOutgoingBonding()) {
-                    mBluetoothService.setBondState(address, BluetoothDevice.BOND_BONDED);
-                }
-            } else {
-                mBluetoothService.setBondState(address, BluetoothDevice.BOND_NONE);
-                mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false");
-            }
-        } else if (name.equals("Trusted")) {
-            if (DBG)
-                log("set trust state succeeded, value is: " + propValues[1]);
-            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
-        }
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.Input.
-     *
-     * @param path the object path for the changed input device
-     * @param propValues a string array containing the key and one or more
-     *  values.
-     */
-    private void onInputDevicePropertyChanged(String path, String[] propValues) {
-        String address = mBluetoothService.getAddressFromObjectPath(path);
-        if (address == null) {
-            Log.e(TAG, "onInputDevicePropertyChanged: Address of the remote device is null");
-            return;
-        }
-        log("Input Device : Name of Property is: " + propValues[0]);
-        boolean state = false;
-        if (propValues[1].equals("true")) {
-            state = true;
-        }
-        mBluetoothService.handleInputDevicePropertyChange(address, state);
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.Network.
-     *
-     * @param deviceObjectPath the object path for the changed PAN device
-     * @param propValues a string array containing the key and one or more
-     *  values.
-     */
-    private void onPanDevicePropertyChanged(String deviceObjectPath, String[] propValues) {
-        String name = propValues[0];
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address == null) {
-            Log.e(TAG, "onPanDevicePropertyChanged: Address of the remote device in null");
-            return;
-        }
-        if (DBG) {
-            log("Pan Device property changed: " + address + "  property: "
-                    + name + " value: "+ propValues[1]);
-        }
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        if (name.equals("Connected")) {
-            if (propValues[1].equals("false")) {
-                mBluetoothService.handlePanDeviceStateChange(device,
-                                          BluetoothPan.STATE_DISCONNECTED,
-                                          BluetoothPan.LOCAL_PANU_ROLE);
-            }
-        } else if (name.equals("Interface")) {
-            String iface = propValues[1];
-            if (!iface.equals("")) {
-                mBluetoothService.handlePanDeviceStateChange(device, iface,
-                                              BluetoothPan.STATE_CONNECTED,
-                                              BluetoothPan.LOCAL_PANU_ROLE);
-            }
-        }
-    }
-
-    private String checkPairingRequestAndGetAddress(String objectPath, int nativeData) {
-        String address = mBluetoothService.getAddressFromObjectPath(objectPath);
-        if (address == null) {
-            Log.e(TAG, "Unable to get device address in checkPairingRequestAndGetAddress, " +
-                  "returning null");
-            return null;
-        }
-        address = address.toUpperCase();
-        mPasskeyAgentRequestData.put(address, new Integer(nativeData));
-
-        if (mBluetoothService.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF) {
-            // shutdown path
-            mBluetoothService.cancelPairingUserInput(address);
-            return null;
-        }
-        // Set state to BONDING. For incoming connections it will be set here.
-        // For outgoing connections, it gets set when we call createBond.
-        // Also set it only when the state is not already Bonded, we can sometimes
-        // get an authorization request from the remote end if it doesn't have the link key
-        // while we still have it.
-        if (mBluetoothService.getBondState(address) != BluetoothDevice.BOND_BONDED)
-            mBluetoothService.setBondState(address, BluetoothDevice.BOND_BONDING);
-        return address;
-    }
-
-    /**
-     * Called by native code on a RequestPairingConsent method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device to request pairing consent for
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onRequestPairingConsent(String objectPath, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-
-        /* The link key will not be stored if the incoming request has MITM
-         * protection switched on. Unfortunately, some devices have MITM
-         * switched on even though their capabilities are NoInputNoOutput,
-         * so we may get this request many times. Also if we respond immediately,
-         * the other end is unable to handle it. Delay sending the message.
-         */
-        if (mBluetoothService.getBondState(address) == BluetoothDevice.BOND_BONDED) {
-            Message message = mHandler.obtainMessage(EVENT_PAIRING_CONSENT_DELAYED_ACCEPT);
-            message.obj = address;
-            mHandler.sendMessageDelayed(message, 1500);
-            return;
-        }
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                        BluetoothDevice.PAIRING_VARIANT_CONSENT);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notification.
-        mWakeLock.release();
-        return;
-    }
-
-    /**
-     * Called by native code on a RequestConfirmation method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device to confirm the passkey for
-     * @param passkey an integer containing the 6-digit passkey to confirm
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, passkey);
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notification.
-        mWakeLock.release();
-        return;
-    }
-
-    /**
-     * Called by native code on a RequestPasskey method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device requesting a passkey
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onRequestPasskey(String objectPath, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                BluetoothDevice.PAIRING_VARIANT_PASSKEY);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notification.
-        mWakeLock.release();
-        return;
-    }
-
-    /**
-     * Called by native code on a RequestPinCode method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device requesting a PIN code
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onRequestPinCode(String objectPath, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-
-        String pendingOutgoingAddress =
-                mBluetoothService.getPendingOutgoingBonding();
-        BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
-        int btDeviceClass = btClass.getDeviceClass();
-
-        if (address.equals(pendingOutgoingAddress)) {
-            // we initiated the bonding
-
-            // Check if its a dock
-            if (mBluetoothService.isBluetoothDock(address)) {
-                String pin = mBluetoothService.getDockPin();
-                mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes(pin));
-                return;
-            }
-
-            // try 0000 once if the device looks dumb
-            switch (btDeviceClass) {
-            case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
-            case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-            case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
-            case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
-            case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
-                if (mBluetoothService.attemptAutoPair(address)) return;
-           }
-        }
-
-        if (btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD ||
-            btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING) {
-            // Its a keyboard. Follow the HID spec recommendation of creating the
-            // passkey and displaying it to the user. If the keyboard doesn't follow
-            // the spec recommendation, check if the keyboard has a fixed PIN zero
-            // and pair.
-            if (mBluetoothService.isFixedPinZerosAutoPairKeyboard(address)) {
-                mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
-                return;
-            }
-
-            // Generate a variable PIN. This is not truly random but good enough.
-            int pin = (int) Math.floor(Math.random() * 10000);
-            sendDisplayPinIntent(address, pin);
-            return;
-        }
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        // Release wakelock to allow the LCD to go off after the PIN popup notification.
-        mWakeLock.release();
-        return;
-    }
-
-    /**
-     * Called by native code on a DisplayPasskey method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device to display the passkey for
-     * @param passkey an integer containing the 6-digit passkey
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onDisplayPasskey(String objectPath, int passkey, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, passkey);
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                        BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        //Release wakelock to allow the LCD to go off after the PIN popup notification.
-        mWakeLock.release();
-    }
-
-    private void sendDisplayPinIntent(String address, int pin) {
-        // Acquire wakelock during PIN code request to bring up LCD display
-        mWakeLock.acquire();
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pin);
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                        BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        //Release wakelock to allow the LCD to go off after the PIN popup notifcation.
-        mWakeLock.release();
-    }
-
-    /**
-     * Called by native code on a RequestOobData method call to
-     * org.bluez.Agent.
-     *
-     * @param objectPath the path of the device requesting OOB data
-     * @param nativeData a native pointer to the original D-Bus message
-     */
-    private void onRequestOobData(String objectPath, int nativeData) {
-        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
-        if (address == null) return;
-
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
-                BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-    }
-
-    /**
-     * Called by native code on an Authorize method call to org.bluez.Agent.
-     *
-     * @param objectPath the path of the device requesting to be authorized
-     * @param deviceUuid the UUID of the requesting device
-     * @param nativeData reference for native data
-     */
-    private void  onAgentAuthorize(String objectPath, String deviceUuid, int nativeData) {
-        if (!mBluetoothService.isEnabled()) return;
-
-        String address = mBluetoothService.getAddressFromObjectPath(objectPath);
-        if (address == null) {
-            Log.e(TAG, "Unable to get device address in onAuthAgentAuthorize");
-            return;
-        }
-
-        boolean authorized = false;
-        ParcelUuid uuid = ParcelUuid.fromString(deviceUuid);
-
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        mAuthorizationAgentRequestData.put(address, new Integer(nativeData));
-
-        // Bluez sends the UUID of the local service being accessed, _not_ the
-        // remote service
-        if (mA2dp != null &&
-            (BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
-              || BluetoothUuid.isAdvAudioDist(uuid)) &&
-              !isOtherSinkInNonDisconnectedState(address)) {
-            authorized = mA2dp.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
-            if (authorized && !BluetoothUuid.isAvrcpTarget(uuid)) {
-                Log.i(TAG, "First check pass for incoming A2DP / AVRCP connection from " + address);
-                // Some headsets try to connect AVCTP before AVDTP - against the recommendation
-                // If AVCTP connection fails, we get stuck in IncomingA2DP state in the state
-                // machine.  We don't handle AVCTP signals currently. We only send
-                // intents for AVDTP state changes. We need to handle both of them in
-                // some cases. For now, just don't move to incoming state in this case.
-                mBluetoothService.notifyIncomingA2dpConnection(address, false);
-            } else {
-                Log.i(TAG, "" + authorized +
-                      "Incoming A2DP / AVRCP connection from " + address);
-                mA2dp.allowIncomingConnect(device, authorized);
-                mBluetoothService.notifyIncomingA2dpConnection(address, true);
-            }
-        } else if (BluetoothUuid.isInputDevice(uuid)) {
-            // We can have more than 1 input device connected.
-            authorized = mBluetoothService.getInputDevicePriority(device) >
-                    BluetoothInputDevice.PRIORITY_OFF;
-            if (authorized) {
-                Log.i(TAG, "First check pass for incoming HID connection from " + address);
-                // notify profile state change
-                mBluetoothService.notifyIncomingHidConnection(address);
-            } else {
-                Log.i(TAG, "Rejecting incoming HID connection from " + address);
-                mBluetoothService.allowIncomingProfileConnect(device, authorized);
-            }
-        } else if (BluetoothUuid.isBnep(uuid)) {
-            // PAN doesn't go to the state machine, accept or reject from here
-            authorized = mBluetoothService.allowIncomingTethering();
-            mBluetoothService.allowIncomingProfileConnect(device, authorized);
-        } else {
-            Log.i(TAG, "Rejecting incoming " + deviceUuid + " connection from " + address);
-            mBluetoothService.allowIncomingProfileConnect(device, authorized);
-        }
-        log("onAgentAuthorize(" + objectPath + ", " + deviceUuid + ") = " + authorized);
-    }
-
-    private boolean onAgentOutOfBandDataAvailable(String objectPath) {
-        if (!mBluetoothService.isEnabled()) return false;
-
-        String address = mBluetoothService.getAddressFromObjectPath(objectPath);
-        if (address == null) return false;
-
-        if (mBluetoothService.getDeviceOutOfBandData(
-            mAdapter.getRemoteDevice(address)) != null) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isOtherSinkInNonDisconnectedState(String address) {
-        List<BluetoothDevice> devices =
-            mA2dp.getDevicesMatchingConnectionStates(new int[] {BluetoothA2dp.STATE_CONNECTED,
-                                                     BluetoothA2dp.STATE_CONNECTING,
-                                                     BluetoothA2dp.STATE_DISCONNECTING});
-
-        if (devices.size() == 0) return false;
-        for (BluetoothDevice dev: devices) {
-            if (!dev.getAddress().equals(address)) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Called by native code on a Cancel method call to org.bluez.Agent.
-     */
-    private void onAgentCancel() {
-        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_AGENT_CANCEL),
-                   1500);
-
-        return;
-    }
-
-    /**
-     * Called by native code for the async response to a DiscoverServices
-     * method call to org.bluez.Adapter.
-     *
-     * @param deviceObjectPath the path for the specified device
-     * @param result true for success; false on error
-     */
-    private void onDiscoverServicesResult(String deviceObjectPath, boolean result) {
-        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address == null) return;
-
-        // We don't parse the xml here, instead just query Bluez for the properties.
-        if (result) {
-            mBluetoothService.updateRemoteDevicePropertiesCache(address);
-        }
-        mBluetoothService.sendUuidIntent(address);
-        mBluetoothService.makeServiceChannelCallbacks(address);
-    }
-
-    /**
-     * Called by native code for the async response to a CreateDevice
-     * method call to org.bluez.Adapter.
-     *
-     * @param address the MAC address of the device to create
-     * @param result {@link #CREATE_DEVICE_SUCCESS},
-     *  {@link #CREATE_DEVICE_ALREADY_EXISTS} or {@link #CREATE_DEVICE_FAILED}}
-     */
-    private void onCreateDeviceResult(String address, int result) {
-        if (DBG) log("Result of onCreateDeviceResult:" + result);
-
-        switch (result) {
-        case CREATE_DEVICE_ALREADY_EXISTS:
-            String path = mBluetoothService.getObjectPathFromAddress(address);
-            if (path != null) {
-                mBluetoothService.discoverServicesNative(path, "");
-                break;
-            }
-            Log.w(TAG, "Device exists, but we don't have the bluez path, failing");
-            // fall-through
-        case CREATE_DEVICE_FAILED:
-            mBluetoothService.sendUuidIntent(address);
-            mBluetoothService.makeServiceChannelCallbacks(address);
-            break;
-        case CREATE_DEVICE_SUCCESS:
-            // nothing to do, UUID intent's will be sent via property changed
-        }
-    }
-
-    /**
-     * Called by native code for the async response to a Connect
-     * method call to org.bluez.Input.
-     *
-     * @param path the path of the specified input device
-     * @param result Result code of the operation.
-     */
-    private void onInputDeviceConnectionResult(String path, int result) {
-        // Success case gets handled by Property Change signal
-        if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
-            String address = mBluetoothService.getAddressFromObjectPath(path);
-            if (address == null) return;
-
-            boolean connected = false;
-            BluetoothDevice device = mAdapter.getRemoteDevice(address);
-            int state = mBluetoothService.getInputDeviceConnectionState(device);
-            if (state == BluetoothInputDevice.STATE_CONNECTING) {
-                if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
-                    connected = true;
-                } else {
-                    connected = false;
-                }
-            } else if (state == BluetoothInputDevice.STATE_DISCONNECTING) {
-                if (result == BluetoothInputDevice.INPUT_DISCONNECT_FAILED_NOT_CONNECTED) {
-                    connected = false;
-                } else {
-                    // There is no better way to handle this, this shouldn't happen
-                    connected = true;
-                }
-            } else {
-                Log.e(TAG, "Error onInputDeviceConnectionResult. State is:" + state);
-            }
-            mBluetoothService.handleInputDevicePropertyChange(address, connected);
-        }
-    }
-
-    /**
-     * Called by native code for the async response to a Connect
-     * method call to org.bluez.Network.
-     *
-     * @param path the path of the specified PAN device
-     * @param result Result code of the operation.
-     */
-    private void onPanDeviceConnectionResult(String path, int result) {
-        log ("onPanDeviceConnectionResult " + path + " " + result);
-        // Success case gets handled by Property Change signal
-        if (result != BluetoothPan.PAN_OPERATION_SUCCESS) {
-            String address = mBluetoothService.getAddressFromObjectPath(path);
-            if (address == null) return;
-
-            boolean connected = false;
-            BluetoothDevice device = mAdapter.getRemoteDevice(address);
-            int state = mBluetoothService.getPanDeviceConnectionState(device);
-            if (state == BluetoothPan.STATE_CONNECTING) {
-                if (result == BluetoothPan.PAN_CONNECT_FAILED_ALREADY_CONNECTED) {
-                    connected = true;
-                } else {
-                    connected = false;
-                }
-            } else if (state == BluetoothPan.STATE_DISCONNECTING) {
-                if (result == BluetoothPan.PAN_DISCONNECT_FAILED_NOT_CONNECTED) {
-                    connected = false;
-                } else {
-                    // There is no better way to handle this, this shouldn't happen
-                    connected = true;
-                }
-            } else {
-                Log.e(TAG, "Error onPanDeviceConnectionResult. State is: "
-                        + state + " result: "+ result);
-            }
-            int newState = connected? BluetoothPan.STATE_CONNECTED :
-                BluetoothPan.STATE_DISCONNECTED;
-            mBluetoothService.handlePanDeviceStateChange(device, newState,
-                                                  BluetoothPan.LOCAL_PANU_ROLE);
-        }
-    }
-
-    /**
-     * Called by native code for the async response to a Connect
-     * method call to org.bluez.Health
-     *
-     * @param chanCode The internal id of the channel
-     * @param result Result code of the operation.
-     */
-    private void onHealthDeviceConnectionResult(int chanCode, int result) {
-        log ("onHealthDeviceConnectionResult " + chanCode + " " + result);
-        // Success case gets handled by Property Change signal
-        if (result != BluetoothHealth.HEALTH_OPERATION_SUCCESS) {
-            mBluetoothService.onHealthDeviceChannelConnectionError(chanCode,
-                                                 BluetoothHealth.STATE_CHANNEL_DISCONNECTED);
-        }
-    }
-
-    /**
-     * Called by native code on a DeviceDisconnected signal from
-     * org.bluez.NetworkServer.
-     *
-     * @param address the MAC address of the disconnected device
-     */
-    private void onNetworkDeviceDisconnected(String address) {
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        mBluetoothService.handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
-                                                      BluetoothPan.LOCAL_NAP_ROLE);
-    }
-
-    /**
-     * Called by native code on a DeviceConnected signal from
-     * org.bluez.NetworkServer.
-     *
-     * @param address the MAC address of the connected device
-     * @param iface interface of remote network
-     * @param destUuid unused UUID parameter
-     */
-    private void onNetworkDeviceConnected(String address, String iface, int destUuid) {
-        BluetoothDevice device = mAdapter.getRemoteDevice(address);
-        mBluetoothService.handlePanDeviceStateChange(device, iface, BluetoothPan.STATE_CONNECTED,
-                                                      BluetoothPan.LOCAL_NAP_ROLE);
-    }
-
-    /**
-     * Called by native code on a PropertyChanged signal from
-     * org.bluez.HealthDevice.
-     *
-     * @param devicePath the object path of the remote device
-     * @param propValues Properties (Name-Value) of the Health Device.
-     */
-    private void onHealthDevicePropertyChanged(String devicePath, String[] propValues) {
-        log("Health Device : Name of Property is: " + propValues[0] + " Value:" + propValues[1]);
-        mBluetoothService.onHealthDevicePropertyChanged(devicePath, propValues[1]);
-    }
-
-    /**
-     * Called by native code on a ChannelCreated/Deleted signal from
-     * org.bluez.HealthDevice.
-     *
-     * @param devicePath the object path of the remote device
-     * @param channelPath the path of the health channel.
-     * @param exists Boolean to indicate if the channel was created or deleted.
-     */
-    private void onHealthDeviceChannelChanged(String devicePath, String channelPath,
-            boolean exists) {
-        log("Health Device : devicePath: " + devicePath + ":channelPath:" + channelPath +
-                ":exists" + exists);
-        mBluetoothService.onHealthDeviceChannelChanged(devicePath, channelPath, exists);
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private native void initializeNativeDataNative();
-    private native void startEventLoopNative();
-    private native void stopEventLoopNative();
-    private native boolean isEventLoopRunningNative();
-    private native void cleanupNativeDataNative();
-}
diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java
deleted file mode 100644
index 5e93b81..0000000
--- a/core/java/android/server/BluetoothHealthProfileHandler.java
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHealth;
-import android.bluetooth.BluetoothHealthAppConfiguration;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHealthCallback;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * This handles all the operations on the Bluetooth Health profile.
- * All functions are called by BluetoothService, as Bluetooth Service
- * is the Service handler for the HDP profile.
- *
- * @hide
- */
-final class BluetoothHealthProfileHandler {
-    private static final String TAG = "BluetoothHealthProfileHandler";
-    private static final boolean DBG = false;
-
-    private static BluetoothHealthProfileHandler sInstance;
-    private BluetoothService mBluetoothService;
-    private ArrayList<HealthChannel> mHealthChannels;
-    private HashMap <BluetoothHealthAppConfiguration, String> mHealthAppConfigs;
-    private HashMap <BluetoothDevice, Integer> mHealthDevices;
-    private HashMap <BluetoothHealthAppConfiguration, IBluetoothHealthCallback> mCallbacks;
-
-    private static final int MESSAGE_REGISTER_APPLICATION = 0;
-    private static final int MESSAGE_UNREGISTER_APPLICATION = 1;
-    private static final int MESSAGE_CONNECT_CHANNEL = 2;
-    private static final AtomicInteger sChannelId = new AtomicInteger();
-
-    class HealthChannel {
-        private ParcelFileDescriptor mChannelFd;
-        private boolean mMainChannel;
-        private String mChannelPath;
-        private BluetoothDevice mDevice;
-        private BluetoothHealthAppConfiguration mConfig;
-        private int mState;
-        private int mChannelType;
-        private int mId;
-
-        HealthChannel(BluetoothDevice device, BluetoothHealthAppConfiguration config,
-                ParcelFileDescriptor fd, boolean mainChannel, String channelPath) {
-             mChannelFd = fd;
-             mMainChannel = mainChannel;
-             mChannelPath = channelPath;
-             mDevice = device;
-             mConfig = config;
-             mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-             mId = getChannelId();
-        }
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MESSAGE_REGISTER_APPLICATION:
-                BluetoothHealthAppConfiguration registerApp =
-                    (BluetoothHealthAppConfiguration) msg.obj;
-                int role = registerApp.getRole();
-                String path = null;
-
-                if (role == BluetoothHealth.SINK_ROLE) {
-                    path = mBluetoothService.registerHealthApplicationNative(
-                            registerApp.getDataType(), getStringRole(role), registerApp.getName());
-                } else {
-                    path = mBluetoothService.registerHealthApplicationNative(
-                            registerApp.getDataType(), getStringRole(role), registerApp.getName(),
-                            getStringChannelType(registerApp.getChannelType()));
-                }
-
-                if (path == null) {
-                    callHealthApplicationStatusCallback(registerApp,
-                            BluetoothHealth.APP_CONFIG_REGISTRATION_FAILURE);
-                    mCallbacks.remove(registerApp);
-                } else {
-                    mHealthAppConfigs.put(registerApp, path);
-                    callHealthApplicationStatusCallback(registerApp,
-                            BluetoothHealth.APP_CONFIG_REGISTRATION_SUCCESS);
-                }
-
-                break;
-            case MESSAGE_UNREGISTER_APPLICATION:
-                BluetoothHealthAppConfiguration unregisterApp =
-                    (BluetoothHealthAppConfiguration) msg.obj;
-
-                // Disconnect all the channels
-                for (HealthChannel chan : mHealthChannels) {
-                    if (chan.mConfig.equals(unregisterApp) &&
-                            chan.mState != BluetoothHealth.STATE_CHANNEL_DISCONNECTED) {
-                        disconnectChannel(chan.mDevice, unregisterApp, chan.mId);
-                    }
-                }
-
-                boolean result = mBluetoothService.unregisterHealthApplicationNative(
-                        mHealthAppConfigs.get(unregisterApp));
-                if (result) {
-                    callHealthApplicationStatusCallback(unregisterApp,
-                            BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS);
-                    mCallbacks.remove(unregisterApp);
-                    mHealthAppConfigs.remove(unregisterApp);
-                } else {
-                    callHealthApplicationStatusCallback(unregisterApp,
-                            BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE);
-                }
-                break;
-            case MESSAGE_CONNECT_CHANNEL:
-                HealthChannel chan = (HealthChannel)msg.obj;
-                String deviceObjectPath =
-                    mBluetoothService.getObjectPathFromAddress(chan.mDevice.getAddress());
-                String configPath = mHealthAppConfigs.get(chan.mConfig);
-                String channelType = getStringChannelType(chan.mChannelType);
-
-                if (!mBluetoothService.createChannelNative(deviceObjectPath, configPath,
-                          channelType, chan.mId)) {
-                    int prevState = chan.mState;
-                    int state = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-                    callHealthChannelCallback(chan.mConfig, chan.mDevice, prevState, state, null,
-                            chan.mId);
-                    mHealthChannels.remove(chan);
-                }
-            }
-        }
-    };
-
-    private BluetoothHealthProfileHandler(Context context, BluetoothService service) {
-        mBluetoothService = service;
-        mHealthAppConfigs = new HashMap<BluetoothHealthAppConfiguration, String>();
-        mHealthChannels = new ArrayList<HealthChannel>();
-        mHealthDevices = new HashMap<BluetoothDevice, Integer>();
-        mCallbacks = new HashMap<BluetoothHealthAppConfiguration, IBluetoothHealthCallback>();
-    }
-
-    static synchronized BluetoothHealthProfileHandler getInstance(Context context,
-            BluetoothService service) {
-        if (sInstance == null) sInstance = new BluetoothHealthProfileHandler(context, service);
-        return sInstance;
-    }
-
-    boolean registerAppConfiguration(BluetoothHealthAppConfiguration config,
-                                     IBluetoothHealthCallback callback) {
-        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_APPLICATION);
-        msg.obj = config;
-        mHandler.sendMessage(msg);
-        mCallbacks.put(config, callback);
-        return true;
-    }
-
-    boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
-        String path = mHealthAppConfigs.get(config);
-        if (path == null) return false;
-
-        Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_APPLICATION);
-        msg.obj = config;
-        mHandler.sendMessage(msg);
-        return true;
-    }
-
-    boolean connectChannelToSource(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        return connectChannel(device, config, BluetoothHealth.CHANNEL_TYPE_ANY);
-    }
-
-    private HealthChannel getMainChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        for (HealthChannel chan: mHealthChannels) {
-            if (chan.mDevice.equals(device) && chan.mConfig.equals(config)) {
-                if (chan.mMainChannel) return chan;
-            }
-        }
-        return null;
-    }
-
-    boolean connectChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config, int channelType) {
-        String deviceObjectPath =
-            mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (deviceObjectPath == null) return false;
-
-        String configPath = mHealthAppConfigs.get(config);
-        if (configPath == null) return false;
-
-        HealthChannel chan = new HealthChannel(device, config, null, false, null);
-        chan.mState = BluetoothHealth.STATE_CHANNEL_CONNECTING;
-        chan.mChannelType = channelType;
-        mHealthChannels.add(chan);
-
-        int prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-        int state = BluetoothHealth.STATE_CHANNEL_CONNECTING;
-        callHealthChannelCallback(config, device, prevState, state, null, chan.mId);
-
-        Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_CHANNEL);
-        msg.obj = chan;
-        mHandler.sendMessage(msg);
-
-        return true;
-    }
-
-    private String getStringChannelType(int type) {
-        if (type == BluetoothHealth.CHANNEL_TYPE_RELIABLE) {
-            return "Reliable";
-        } else if (type == BluetoothHealth.CHANNEL_TYPE_STREAMING) {
-            return "Streaming";
-        } else {
-            return "Any";
-        }
-    }
-
-    private String getStringRole(int role) {
-        if (role == BluetoothHealth.SINK_ROLE) {
-            return "Sink";
-        } else if (role == BluetoothHealth.SOURCE_ROLE) {
-            return "Streaming";
-        } else {
-            return null;
-        }
-    }
-
-    private int getChannelId() {
-        // The function doesn't need to be synchronized, as the health profile handler
-        // will only allow one health channel object creation at a time.
-        // In the worst case the while loop will have to break out at some point of
-        // time, because only a limited number of L2CAP channels are possible.
-        int id;
-        boolean found;
-        do {
-            id = sChannelId.incrementAndGet();
-            found = false;
-            for (HealthChannel chan: mHealthChannels) {
-                if (chan.mId == id) found = true;
-            }
-        } while (found);
-        return id;
-    }
-
-    boolean disconnectChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config, int id) {
-        HealthChannel chan = findChannelById(id);
-        if (chan == null) {
-          return false;
-        }
-
-        String deviceObjectPath =
-                mBluetoothService.getObjectPathFromAddress(device.getAddress());
-
-        mBluetoothService.releaseChannelFdNative(chan.mChannelPath);
-
-        int prevState = chan.mState;
-        chan.mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTING;
-        callHealthChannelCallback(config, device, prevState, chan.mState,
-                null, chan.mId);
-
-        if (!mBluetoothService.destroyChannelNative(deviceObjectPath, chan.mChannelPath,
-                                                    chan.mId)) {
-            prevState = chan.mState;
-            chan.mState = BluetoothHealth.STATE_CHANNEL_CONNECTED;
-            callHealthChannelCallback(config, device, prevState, chan.mState,
-                    chan.mChannelFd, chan.mId);
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    private HealthChannel findChannelById(int id) {
-        for (HealthChannel chan : mHealthChannels) {
-            if (chan.mId == id) return chan;
-        }
-        return null;
-    }
-
-    private HealthChannel findChannelByPath(BluetoothDevice device, String path) {
-        for (HealthChannel chan : mHealthChannels) {
-            if (path.equals(chan.mChannelPath) && device.equals(chan.mDevice)) return chan;
-        }
-        return null;
-    }
-
-    private List<HealthChannel> findChannelByStates(BluetoothDevice device, int[] states) {
-        List<HealthChannel> channels = new ArrayList<HealthChannel>();
-        for (HealthChannel chan: mHealthChannels) {
-            if (chan.mDevice.equals(device)) {
-                for (int state : states) {
-                    if (chan.mState == state) {
-                        channels.add(chan);
-                    }
-                }
-            }
-        }
-        return channels;
-    }
-
-    private HealthChannel findConnectingChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        for (HealthChannel chan : mHealthChannels) {
-            if (chan.mDevice.equals(device) && chan.mConfig.equals(config) &&
-                chan.mState == BluetoothHealth.STATE_CHANNEL_CONNECTING) return chan;
-        }
-        return null;
-    }
-
-    ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        HealthChannel chan = getMainChannel(device, config);
-        if (chan != null) {
-            ParcelFileDescriptor pfd =  null;
-            try {
-                pfd = chan.mChannelFd.dup();
-                return pfd;
-            } catch (IOException e) {
-                return null;
-            }
-        }
-
-        String objectPath =
-                mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (objectPath == null) return null;
-
-        String mainChannelPath = mBluetoothService.getMainChannelNative(objectPath);
-        if (mainChannelPath == null) return null;
-
-        // We had no record of the main channel but querying Bluez we got a
-        // main channel. We might not have received the PropertyChanged yet for
-        // the main channel creation so update our data structure here.
-        chan = findChannelByPath(device, mainChannelPath);
-        if (chan == null) {
-            errorLog("Main Channel present but we don't have any account of it:" +
-                    device +":" + config);
-            return null;
-        }
-        chan.mMainChannel = true;
-        try {
-            return chan.mChannelFd.dup();
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    /*package*/ void onHealthDevicePropertyChanged(String devicePath,
-            String channelPath) {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        String address = mBluetoothService.getAddressFromObjectPath(devicePath);
-        if (address == null) return;
-
-        //TODO: Fix this in Bluez
-        if (channelPath.equals("/")) {
-            // This means that the main channel is being destroyed.
-            return;
-        }
-
-        BluetoothDevice device = adapter.getRemoteDevice(address);
-        BluetoothHealthAppConfiguration config = findHealthApplication(device,
-                channelPath);
-        if (config != null) {
-            HealthChannel chan = findChannelByPath(device, channelPath);
-            if (chan == null) {
-                errorLog("Health Channel is not present:" + channelPath);
-            } else {
-                chan.mMainChannel = true;
-            }
-        }
-    }
-
-    /*package*/ void onHealthDeviceChannelConnectionError(int chanCode,
-                                                          int state) {
-        HealthChannel channel = findChannelById(chanCode);
-        if (channel == null) errorLog("No record of this channel:" + chanCode);
-
-        callHealthChannelCallback(channel.mConfig, channel.mDevice, channel.mState, state, null,
-                chanCode);
-    }
-
-    private BluetoothHealthAppConfiguration findHealthApplication(
-            BluetoothDevice device, String channelPath) {
-        BluetoothHealthAppConfiguration config = null;
-        HealthChannel chan = findChannelByPath(device, channelPath);
-
-        if (chan != null) {
-            config = chan.mConfig;
-        } else {
-            String configPath = mBluetoothService.getChannelApplicationNative(channelPath);
-            if (configPath == null) {
-                errorLog("Config path is null for application");
-            } else {
-                for (Entry<BluetoothHealthAppConfiguration, String> e :
-                        mHealthAppConfigs.entrySet()) {
-                    if (e.getValue().equals(configPath)) {
-                        config = e.getKey();
-                    }
-                }
-                if (config == null) errorLog("No associated application for path:" + configPath);
-            }
-        }
-        return config;
-    }
-
-    /*package*/ void onHealthDeviceChannelChanged(String devicePath,
-            String channelPath, boolean exists) {
-        debugLog("onHealthDeviceChannelChanged: devicePath: " + devicePath +
-                "ChannelPath: " + channelPath + "Exists: " + exists);
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        String address = mBluetoothService.getAddressFromObjectPath(devicePath);
-        if (address == null) return;
-
-        BluetoothDevice device = adapter.getRemoteDevice(address);
-        BluetoothHealthAppConfiguration config;
-        int state, prevState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-        ParcelFileDescriptor fd;
-        HealthChannel channel;
-        config = findHealthApplication(device, channelPath);
-
-        if (exists) {
-            channel = findConnectingChannel(device, config);
-            if (channel == null) {
-               channel = new HealthChannel(device, config, null, false,
-                       channelPath);
-               channel.mState = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-               mHealthChannels.add(channel);
-            }
-            channel.mChannelPath = channelPath;
-
-            fd = mBluetoothService.getChannelFdNative(channelPath);
-            if (fd == null) {
-                errorLog("Error obtaining fd for channel:" + channelPath);
-                disconnectChannel(device, config, channel.mId);
-                return;
-            }
-            boolean mainChannel =
-                    getMainChannel(device, config) == null ? false : true;
-            if (!mainChannel) {
-                String mainChannelPath =
-                        mBluetoothService.getMainChannelNative(devicePath);
-                if (mainChannelPath == null) {
-                    errorLog("Main Channel Path is null for devicePath:" + devicePath);
-                    return;
-                }
-                if (mainChannelPath.equals(channelPath)) mainChannel = true;
-            }
-
-            channel.mChannelFd = fd;
-            channel.mMainChannel = mainChannel;
-            prevState = channel.mState;
-            state = BluetoothHealth.STATE_CHANNEL_CONNECTED;
-        } else {
-            channel = findChannelByPath(device, channelPath);
-            if (channel == null) {
-                errorLog("Channel not found:" + config + ":" + channelPath);
-                return;
-            }
-            mHealthChannels.remove(channel);
-
-            channel.mChannelFd = null;
-            prevState = channel.mState;
-            state = BluetoothHealth.STATE_CHANNEL_DISCONNECTED;
-        }
-        channel.mState = state;
-        callHealthChannelCallback(config, device, prevState, state, channel.mChannelFd,
-                channel.mId);
-    }
-
-    private void callHealthChannelCallback(BluetoothHealthAppConfiguration config,
-            BluetoothDevice device, int prevState, int state, ParcelFileDescriptor fd, int id) {
-        broadcastHealthDeviceStateChange(device, prevState, state);
-
-        debugLog("Health Device Callback: " + device + " State Change: "
-                + prevState + "->" + state);
-
-        ParcelFileDescriptor dupedFd = null;
-        if (fd != null) {
-            try {
-                dupedFd = fd.dup();
-            } catch (IOException e) {
-                dupedFd = null;
-                errorLog("Exception while duping: " + e);
-            }
-        }
-
-        IBluetoothHealthCallback callback = mCallbacks.get(config);
-        if (callback != null) {
-            try {
-                callback.onHealthChannelStateChange(config, device, prevState, state, dupedFd, id);
-            } catch (RemoteException e) {
-                errorLog("Remote Exception:" + e);
-            }
-        }
-    }
-
-    private void callHealthApplicationStatusCallback(
-            BluetoothHealthAppConfiguration config, int status) {
-        debugLog("Health Device Application: " + config + " State Change: status:"
-                + status);
-        IBluetoothHealthCallback callback = mCallbacks.get(config);
-        if (callback != null) {
-            try {
-                callback.onHealthAppConfigurationStatusChange(config, status);
-            } catch (RemoteException e) {
-                errorLog("Remote Exception:" + e);
-            }
-        }
-    }
-
-    int getHealthDeviceConnectionState(BluetoothDevice device) {
-        if (mHealthDevices.get(device) == null) {
-            return BluetoothHealth.STATE_DISCONNECTED;
-        }
-        return mHealthDevices.get(device);
-    }
-
-    List<BluetoothDevice> getConnectedHealthDevices() {
-        List<BluetoothDevice> devices = lookupHealthDevicesMatchingStates(
-                    new int[] {BluetoothHealth.STATE_CONNECTED});
-        return devices;
-    }
-
-    List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(int[] states) {
-        List<BluetoothDevice> devices = lookupHealthDevicesMatchingStates(states);
-        return devices;
-    }
-
-    List<BluetoothDevice> lookupHealthDevicesMatchingStates(int[] states) {
-        List<BluetoothDevice> healthDevices = new ArrayList<BluetoothDevice>();
-
-        for (BluetoothDevice device: mHealthDevices.keySet()) {
-            int healthDeviceState = getHealthDeviceConnectionState(device);
-            for (int state : states) {
-                if (state == healthDeviceState) {
-                    healthDevices.add(device);
-                    break;
-                }
-            }
-        }
-        return healthDevices;
-    }
-
-    /**
-     * This function sends the intent for the updates on the connection status to the remote device.
-     * Note that multiple channels can be connected to the remote device by multiple applications.
-     * This sends an intent for the update to the device connection status and not the channel
-     * connection status. Only the following state transitions are possible:
-     *
-     * {@link BluetoothHealth#STATE_DISCONNECTED} to {@link BluetoothHealth#STATE_CONNECTING}
-     * {@link BluetoothHealth#STATE_CONNECTING} to {@link BluetoothHealth#STATE_CONNECTED}
-     * {@link BluetoothHealth#STATE_CONNECTED} to {@link BluetoothHealth#STATE_DISCONNECTING}
-     * {@link BluetoothHealth#STATE_DISCONNECTING} to {@link BluetoothHealth#STATE_DISCONNECTED}
-     * {@link BluetoothHealth#STATE_DISCONNECTED} to {@link BluetoothHealth#STATE_CONNECTED}
-     * {@link BluetoothHealth#STATE_CONNECTED} to {@link BluetoothHealth#STATE_DISCONNECTED}
-     * {@link BluetoothHealth#STATE_CONNECTING} to {{@link BluetoothHealth#STATE_DISCONNECTED}
-     *
-     * @param device
-     * @param prevChannelState
-     * @param newChannelState
-     * @hide
-     */
-    private void broadcastHealthDeviceStateChange(BluetoothDevice device, int prevChannelState,
-            int newChannelState) {
-        if (mHealthDevices.get(device) == null) {
-            mHealthDevices.put(device, BluetoothHealth.STATE_DISCONNECTED);
-        }
-
-        int currDeviceState = mHealthDevices.get(device);
-        int newDeviceState = convertState(newChannelState);
-
-        if (currDeviceState != newDeviceState) {
-            List<HealthChannel> chan;
-            switch (currDeviceState) {
-                case BluetoothHealth.STATE_DISCONNECTED:
-                    updateAndSendIntent(device, currDeviceState, newDeviceState);
-                    break;
-                case BluetoothHealth.STATE_CONNECTING:
-                    // Channel got connected.
-                    if (newDeviceState == BluetoothHealth.STATE_CONNECTED) {
-                        updateAndSendIntent(device, currDeviceState, newDeviceState);
-                    } else {
-                        // Channel got disconnected
-                        chan = findChannelByStates(device, new int [] {
-                                    BluetoothHealth.STATE_CHANNEL_CONNECTING,
-                                    BluetoothHealth.STATE_CHANNEL_DISCONNECTING});
-                        if (chan.isEmpty()) {
-                            updateAndSendIntent(device, currDeviceState, newDeviceState);
-                        }
-                    }
-                    break;
-                case BluetoothHealth.STATE_CONNECTED:
-                    // Channel got disconnected or is in disconnecting state.
-                    chan = findChannelByStates(device, new int [] {
-                                BluetoothHealth.STATE_CHANNEL_CONNECTING,
-                                BluetoothHealth.STATE_CHANNEL_CONNECTED});
-                    if (chan.isEmpty()) {
-                        updateAndSendIntent(device, currDeviceState, newDeviceState);
-                    }
-                    break;
-                case BluetoothHealth.STATE_DISCONNECTING:
-                    // Channel got disconnected.
-                    chan = findChannelByStates(device, new int [] {
-                                BluetoothHealth.STATE_CHANNEL_CONNECTING,
-                                BluetoothHealth.STATE_CHANNEL_DISCONNECTING});
-                    if (chan.isEmpty()) {
-                        updateAndSendIntent(device, currDeviceState, newDeviceState);
-                    }
-                    break;
-            }
-        }
-    }
-
-    private void updateAndSendIntent(BluetoothDevice device, int prevDeviceState,
-            int newDeviceState) {
-        mHealthDevices.put(device, newDeviceState);
-        mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.HEALTH,
-                                                    newDeviceState, prevDeviceState);
-    }
-
-    /**
-     * This function converts the channel connection state to device connection state.
-     *
-     * @param state
-     * @return
-     */
-    private int convertState(int state) {
-        switch (state) {
-            case BluetoothHealth.STATE_CHANNEL_CONNECTED:
-                return BluetoothHealth.STATE_CONNECTED;
-            case BluetoothHealth.STATE_CHANNEL_CONNECTING:
-                return BluetoothHealth.STATE_CONNECTING;
-            case BluetoothHealth.STATE_CHANNEL_DISCONNECTING:
-                return BluetoothHealth.STATE_DISCONNECTING;
-            case BluetoothHealth.STATE_CHANNEL_DISCONNECTED:
-                return BluetoothHealth.STATE_DISCONNECTED;
-        }
-        errorLog("Mismatch in Channel and Health Device State");
-        return -1;
-    }
-
-    private static void debugLog(String msg) {
-        if (DBG) Log.d(TAG, msg);
-    }
-
-    private static void errorLog(String msg) {
-        Log.e(TAG, msg);
-    }
-}
diff --git a/core/java/android/server/BluetoothInputProfileHandler.java b/core/java/android/server/BluetoothInputProfileHandler.java
deleted file mode 100644
index 31764b0..0000000
--- a/core/java/android/server/BluetoothInputProfileHandler.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothDeviceProfileState;
-import android.bluetooth.BluetoothInputDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfileState;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Message;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This handles all the operations on the HID profile.
- * All functions are called by BluetoothService, as Bluetooth Service
- * is the Service handler for the HID profile.
- */
-final class BluetoothInputProfileHandler {
-    private static final String TAG = "BluetoothInputProfileHandler";
-    private static final boolean DBG = true;
-
-    public static BluetoothInputProfileHandler sInstance;
-    private Context mContext;
-    private BluetoothService mBluetoothService;
-    private final HashMap<BluetoothDevice, Integer> mInputDevices;
-    private final BluetoothProfileState mHidProfileState;
-
-    private BluetoothInputProfileHandler(Context context, BluetoothService service) {
-        mContext = context;
-        mBluetoothService = service;
-        mInputDevices = new HashMap<BluetoothDevice, Integer>();
-        mHidProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HID);
-        mHidProfileState.start();
-    }
-
-    static synchronized BluetoothInputProfileHandler getInstance(Context context,
-            BluetoothService service) {
-        if (sInstance == null) sInstance = new BluetoothInputProfileHandler(context, service);
-        return sInstance;
-    }
-
-    boolean connectInputDevice(BluetoothDevice device,
-                                            BluetoothDeviceProfileState state) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (objectPath == null ||
-            getInputDeviceConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
-            getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_OFF) {
-            return false;
-        }
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.CONNECT_HID_OUTGOING;
-            msg.obj = state;
-            mHidProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    boolean connectInputDeviceInternal(BluetoothDevice device) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_CONNECTING);
-        if (!mBluetoothService.connectInputDeviceNative(objectPath)) {
-            handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_DISCONNECTED);
-            return false;
-        }
-        return true;
-    }
-
-    boolean disconnectInputDevice(BluetoothDevice device,
-                                               BluetoothDeviceProfileState state) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (objectPath == null ||
-                getInputDeviceConnectionState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
-            return false;
-        }
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.DISCONNECT_HID_OUTGOING;
-            msg.obj = state;
-            mHidProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    boolean disconnectInputDeviceInternal(BluetoothDevice device) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_DISCONNECTING);
-        if (!mBluetoothService.disconnectInputDeviceNative(objectPath)) {
-            handleInputDeviceStateChange(device, BluetoothInputDevice.STATE_CONNECTED);
-            return false;
-        }
-        return true;
-    }
-
-    int getInputDeviceConnectionState(BluetoothDevice device) {
-        if (mInputDevices.get(device) == null) {
-            return BluetoothInputDevice.STATE_DISCONNECTED;
-        }
-        return mInputDevices.get(device);
-    }
-
-    List<BluetoothDevice> getConnectedInputDevices() {
-        List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(
-            new int[] {BluetoothInputDevice.STATE_CONNECTED});
-        return devices;
-    }
-
-    List<BluetoothDevice> getInputDevicesMatchingConnectionStates(int[] states) {
-        List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(states);
-        return devices;
-    }
-
-    int getInputDevicePriority(BluetoothDevice device) {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
-                BluetoothInputDevice.PRIORITY_UNDEFINED);
-    }
-
-    boolean setInputDevicePriority(BluetoothDevice device, int priority) {
-        if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
-            return false;
-        }
-        return Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
-                priority);
-    }
-
-    List<BluetoothDevice> lookupInputDevicesMatchingStates(int[] states) {
-        List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>();
-
-        for (BluetoothDevice device: mInputDevices.keySet()) {
-            int inputDeviceState = getInputDeviceConnectionState(device);
-            for (int state : states) {
-                if (state == inputDeviceState) {
-                    inputDevices.add(device);
-                    break;
-                }
-            }
-        }
-        return inputDevices;
-    }
-
-    private void handleInputDeviceStateChange(BluetoothDevice device, int state) {
-        int prevState;
-        if (mInputDevices.get(device) == null) {
-            prevState = BluetoothInputDevice.STATE_DISCONNECTED;
-        } else {
-            prevState = mInputDevices.get(device);
-        }
-        if (prevState == state) return;
-
-        mInputDevices.put(device, state);
-
-        if (getInputDevicePriority(device) >
-              BluetoothInputDevice.PRIORITY_OFF &&
-            state == BluetoothInputDevice.STATE_CONNECTING ||
-            state == BluetoothInputDevice.STATE_CONNECTED) {
-            // We have connected or attempting to connect.
-            // Bump priority
-            setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_AUTO_CONNECT);
-        }
-
-        Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-        intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_STATE, prevState);
-        intent.putExtra(BluetoothInputDevice.EXTRA_STATE, state);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
-
-        debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
-        mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.INPUT_DEVICE, state,
-                                                    prevState);
-    }
-
-    void handleInputDevicePropertyChange(String address, boolean connected) {
-        int state = connected ? BluetoothInputDevice.STATE_CONNECTED :
-            BluetoothInputDevice.STATE_DISCONNECTED;
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        BluetoothDevice device = adapter.getRemoteDevice(address);
-        handleInputDeviceStateChange(device, state);
-    }
-
-    void setInitialInputDevicePriority(BluetoothDevice device, int state) {
-        switch (state) {
-            case BluetoothDevice.BOND_BONDED:
-                if (getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_UNDEFINED) {
-                    setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_ON);
-                }
-                break;
-            case BluetoothDevice.BOND_NONE:
-                setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_UNDEFINED);
-                break;
-        }
-    }
-
-    private static void debugLog(String msg) {
-        if (DBG) Log.d(TAG, msg);
-    }
-
-    private static void errorLog(String msg) {
-        Log.e(TAG, msg);
-    }
-}
diff --git a/core/java/android/server/BluetoothPanProfileHandler.java b/core/java/android/server/BluetoothPanProfileHandler.java
deleted file mode 100644
index 41bb87f..0000000
--- a/core/java/android/server/BluetoothPanProfileHandler.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothTetheringDataTracker;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources.NotFoundException;
-import android.net.ConnectivityManager;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
-import android.os.ServiceManager;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This handles the PAN profile. All calls into this are made
- * from Bluetooth Service.
- */
-final class BluetoothPanProfileHandler {
-    private static final String TAG = "BluetoothPanProfileHandler";
-    private static final boolean DBG = true;
-
-    private ArrayList<String> mBluetoothIfaceAddresses;
-    private int mMaxPanDevices;
-
-    private static final String BLUETOOTH_IFACE_ADDR_START= "192.168.44.1";
-    private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5;
-    private static final int BLUETOOTH_PREFIX_LENGTH        = 24;
-    public static BluetoothPanProfileHandler sInstance;
-    private final HashMap<BluetoothDevice, BluetoothPanDevice> mPanDevices;
-    private boolean mTetheringOn;
-    private Context mContext;
-    private BluetoothService mBluetoothService;
-
-    static final String NAP_ROLE = "nap";
-    static final String NAP_BRIDGE = "pan1";
-
-    private BluetoothPanProfileHandler(Context context, BluetoothService service) {
-        mContext = context;
-        mPanDevices = new HashMap<BluetoothDevice, BluetoothPanDevice>();
-        mBluetoothService = service;
-        mTetheringOn = false;
-        mBluetoothIfaceAddresses = new ArrayList<String>();
-        try {
-            mMaxPanDevices = context.getResources().getInteger(
-                            com.android.internal.R.integer.config_max_pan_devices);
-        } catch (NotFoundException e) {
-            mMaxPanDevices = BLUETOOTH_MAX_PAN_CONNECTIONS;
-        }
-    }
-
-    static BluetoothPanProfileHandler getInstance(Context context,
-            BluetoothService service) {
-        if (sInstance == null) sInstance = new BluetoothPanProfileHandler(context, service);
-        return sInstance;
-    }
-
-    boolean isTetheringOn() {
-        return mTetheringOn;
-    }
-
-    boolean allowIncomingTethering() {
-        if (isTetheringOn() && getConnectedPanDevices().size() < mMaxPanDevices)
-            return true;
-        return false;
-    }
-
-    private BroadcastReceiver mTetheringReceiver = null;
-
-    void setBluetoothTethering(boolean value) {
-        if (!value) {
-            disconnectPanServerDevices();
-        }
-
-        if (mBluetoothService.getBluetoothState() != BluetoothAdapter.STATE_ON && value) {
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-            mTetheringReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF)
-                            == BluetoothAdapter.STATE_ON) {
-                        mTetheringOn = true;
-                        mContext.unregisterReceiver(mTetheringReceiver);
-                    }
-                }
-            };
-            mContext.registerReceiver(mTetheringReceiver, filter);
-        } else {
-            mTetheringOn = value;
-        }
-    }
-
-    int getPanDeviceConnectionState(BluetoothDevice device) {
-        BluetoothPanDevice panDevice = mPanDevices.get(device);
-        if (panDevice == null) {
-            return BluetoothPan.STATE_DISCONNECTED;
-        }
-        return panDevice.mState;
-    }
-
-    boolean connectPanDevice(BluetoothDevice device) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        if (DBG) Log.d(TAG, "connect PAN(" + objectPath + ")");
-        if (getPanDeviceConnectionState(device) != BluetoothPan.STATE_DISCONNECTED) {
-            errorLog(device + " already connected to PAN");
-        }
-
-        int connectedCount = 0;
-        for (BluetoothDevice panDevice: mPanDevices.keySet()) {
-            if (getPanDeviceConnectionState(panDevice) == BluetoothPan.STATE_CONNECTED) {
-                connectedCount ++;
-            }
-        }
-        if (connectedCount > 8) {
-            debugLog(device + " could not connect to PAN because 8 other devices are"
-                    + "already connected");
-            return false;
-        }
-
-        // Send interface as null as it is not known
-        handlePanDeviceStateChange(device, null, BluetoothPan.STATE_CONNECTING,
-                                           BluetoothPan.LOCAL_PANU_ROLE);
-        if (mBluetoothService.connectPanDeviceNative(objectPath, "nap")) {
-            debugLog("connecting to PAN");
-            return true;
-        } else {
-            handlePanDeviceStateChange(device, null, BluetoothPan.STATE_DISCONNECTED,
-                                                BluetoothPan.LOCAL_PANU_ROLE);
-            errorLog("could not connect to PAN");
-            return false;
-        }
-    }
-
-    private boolean disconnectPanServerDevices() {
-        debugLog("disconnect all PAN devices");
-
-        for (BluetoothDevice device: mPanDevices.keySet()) {
-            BluetoothPanDevice panDevice = mPanDevices.get(device);
-            int state = panDevice.mState;
-            if (state == BluetoothPan.STATE_CONNECTED &&
-                    panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
-                String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-
-                handlePanDeviceStateChange(device, panDevice.mIface,
-                        BluetoothPan.STATE_DISCONNECTING, panDevice.mLocalRole);
-
-                if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath,
-                        device.getAddress(),
-                        panDevice.mIface)) {
-                    errorLog("could not disconnect Pan Server Device "+device.getAddress());
-
-                    // Restore prev state
-                    handlePanDeviceStateChange(device, panDevice.mIface, state,
-                            panDevice.mLocalRole);
-
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    List<BluetoothDevice> getConnectedPanDevices() {
-        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
-
-        for (BluetoothDevice device: mPanDevices.keySet()) {
-            if (getPanDeviceConnectionState(device) == BluetoothPan.STATE_CONNECTED) {
-                devices.add(device);
-            }
-        }
-        return devices;
-    }
-
-    List<BluetoothDevice> getPanDevicesMatchingConnectionStates(int[] states) {
-        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
-
-        for (BluetoothDevice device: mPanDevices.keySet()) {
-            int panDeviceState = getPanDeviceConnectionState(device);
-            for (int state : states) {
-                if (state == panDeviceState) {
-                    devices.add(device);
-                    break;
-                }
-            }
-        }
-        return devices;
-    }
-
-    boolean disconnectPanDevice(BluetoothDevice device) {
-        String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
-        debugLog("disconnect PAN(" + objectPath + ")");
-
-        int state = getPanDeviceConnectionState(device);
-        if (state != BluetoothPan.STATE_CONNECTED) {
-            debugLog(device + " already disconnected from PAN");
-            return false;
-        }
-
-        BluetoothPanDevice panDevice = mPanDevices.get(device);
-
-        if (panDevice == null) {
-            errorLog("No record for this Pan device:" + device);
-            return false;
-        }
-
-        handlePanDeviceStateChange(device, panDevice.mIface, BluetoothPan.STATE_DISCONNECTING,
-                                    panDevice.mLocalRole);
-        if (panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
-            if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath, device.getAddress(),
-                    panDevice.mIface)) {
-                // Restore prev state, this shouldn't happen
-                handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
-                return false;
-            }
-        } else {
-            if (!mBluetoothService.disconnectPanDeviceNative(objectPath)) {
-                // Restore prev state, this shouldn't happen
-                handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    void handlePanDeviceStateChange(BluetoothDevice device,
-                                                 String iface, int state, int role) {
-        int prevState;
-        String ifaceAddr = null;
-        BluetoothPanDevice panDevice = mPanDevices.get(device);
-
-        if (panDevice == null) {
-            prevState = BluetoothPan.STATE_DISCONNECTED;
-        } else {
-            prevState = panDevice.mState;
-            ifaceAddr = panDevice.mIfaceAddr;
-        }
-        if (prevState == state) return;
-
-        if (role == BluetoothPan.LOCAL_NAP_ROLE) {
-            if (state == BluetoothPan.STATE_CONNECTED) {
-                ifaceAddr = enableTethering(iface);
-                if (ifaceAddr == null) Log.e(TAG, "Error seting up tether interface");
-            } else if (state == BluetoothPan.STATE_DISCONNECTED) {
-                if (ifaceAddr != null) {
-                    mBluetoothIfaceAddresses.remove(ifaceAddr);
-                    ifaceAddr = null;
-                }
-            }
-        } else {
-            // PANU Role = reverse Tether
-            if (state == BluetoothPan.STATE_CONNECTED) {
-                BluetoothTetheringDataTracker.getInstance().startReverseTether(iface, device);
-            } else if (state == BluetoothPan.STATE_DISCONNECTED &&
-                  (prevState == BluetoothPan.STATE_CONNECTED ||
-                  prevState == BluetoothPan.STATE_DISCONNECTING)) {
-                BluetoothTetheringDataTracker.getInstance().stopReverseTether(panDevice.mIface);
-            }
-        }
-
-        if (panDevice == null) {
-            panDevice = new BluetoothPanDevice(state, ifaceAddr, iface, role);
-            mPanDevices.put(device, panDevice);
-        } else {
-            panDevice.mState = state;
-            panDevice.mIfaceAddr = ifaceAddr;
-            panDevice.mLocalRole = role;
-            panDevice.mIface = iface;
-        }
-
-        Intent intent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-        intent.putExtra(BluetoothPan.EXTRA_PREVIOUS_STATE, prevState);
-        intent.putExtra(BluetoothPan.EXTRA_STATE, state);
-        intent.putExtra(BluetoothPan.EXTRA_LOCAL_ROLE, role);
-        mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
-
-        debugLog("Pan Device state : device: " + device + " State:" + prevState + "->" + state);
-        mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.PAN, state,
-                                                    prevState);
-    }
-
-    private class BluetoothPanDevice {
-        private int mState;
-        private String mIfaceAddr;
-        private String mIface;
-        private int mLocalRole; // Which local role is this PAN device bound to
-
-        BluetoothPanDevice(int state, String ifaceAddr, String iface, int localRole) {
-            mState = state;
-            mIfaceAddr = ifaceAddr;
-            mIface = iface;
-            mLocalRole = localRole;
-        }
-    }
-
-    private String createNewTetheringAddressLocked() {
-        if (getConnectedPanDevices().size() == mMaxPanDevices) {
-            debugLog ("Max PAN device connections reached");
-            return null;
-        }
-        String address = BLUETOOTH_IFACE_ADDR_START;
-        while (true) {
-            if (mBluetoothIfaceAddresses.contains(address)) {
-                String[] addr = address.split("\\.");
-                Integer newIp = Integer.parseInt(addr[2]) + 1;
-                address = address.replace(addr[2], newIp.toString());
-            } else {
-                break;
-            }
-        }
-        mBluetoothIfaceAddresses.add(address);
-        return address;
-    }
-
-    // configured when we start tethering
-    private String enableTethering(String iface) {
-        debugLog("updateTetherState:" + iface);
-
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-        ConnectivityManager cm =
-            (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs();
-
-        // bring toggle the interfaces
-        String[] currentIfaces = new String[0];
-        try {
-            currentIfaces = service.listInterfaces();
-        } catch (Exception e) {
-            Log.e(TAG, "Error listing Interfaces :" + e);
-            return null;
-        }
-
-        boolean found = false;
-        for (String currIface: currentIfaces) {
-            if (currIface.equals(iface)) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) return null;
-
-        String address = createNewTetheringAddressLocked();
-        if (address == null) return null;
-
-        InterfaceConfiguration ifcg = null;
-        try {
-            ifcg = service.getInterfaceConfig(iface);
-            if (ifcg != null) {
-                final LinkAddress linkAddr = ifcg.getLinkAddress();
-                InetAddress addr = null;
-                if (linkAddr == null || (addr = linkAddr.getAddress()) == null ||
-                        addr.equals(NetworkUtils.numericToInetAddress("0.0.0.0")) ||
-                        addr.equals(NetworkUtils.numericToInetAddress("::0"))) {
-                    addr = NetworkUtils.numericToInetAddress(address);
-                }
-                ifcg.setInterfaceUp();
-                ifcg.clearFlag("running");
-                ifcg.setLinkAddress(new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH));
-                service.setInterfaceConfig(iface, ifcg);
-                if (cm.tether(iface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                    Log.e(TAG, "Error tethering "+iface);
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Error configuring interface " + iface + ", :" + e);
-            return null;
-        }
-        return address;
-    }
-
-    private static void debugLog(String msg) {
-        if (DBG) Log.d(TAG, msg);
-    }
-
-    private static void errorLog(String msg) {
-        Log.e(TAG, msg);
-    }
-}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
deleted file mode 100755
index 6296b11..0000000
--- a/core/java/android/server/BluetoothService.java
+++ /dev/null
@@ -1,2924 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * TODO: Move this to
- * java/services/com/android/server/BluetoothService.java
- * and make the contructor package private again.
- *
- * @hide
- */
-
-package android.server;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothDeviceProfileState;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothHealthAppConfiguration;
-import android.bluetooth.BluetoothInputDevice;
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfileState;
-import android.bluetooth.BluetoothSocket;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.IBluetooth;
-import android.bluetooth.IBluetoothCallback;
-import android.bluetooth.IBluetoothHealthCallback;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.ParcelUuid;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.Pair;
-
-import com.android.internal.app.IBatteryStats;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-public class BluetoothService extends IBluetooth.Stub {
-    private static final String TAG = "BluetoothService";
-    private static final boolean DBG = true;
-
-    private int mNativeData;
-    private BluetoothEventLoop mEventLoop;
-    private BluetoothHeadset mHeadsetProxy;
-    private BluetoothInputDevice mInputDevice;
-    private BluetoothPan mPan;
-    private boolean mIsAirplaneSensitive;
-    private boolean mIsAirplaneToggleable;
-    private BluetoothAdapterStateMachine mBluetoothState;
-    private int[] mAdapterSdpHandles;
-    private ParcelUuid[] mAdapterUuids;
-
-    private BluetoothAdapter mAdapter;  // constant after init()
-    private final BluetoothBondState mBondState;  // local cache of bondings
-    private final IBatteryStats mBatteryStats;
-    private final Context mContext;
-    private Map<Integer, IBluetoothStateChangeCallback> mStateChangeTracker =
-        Collections.synchronizedMap(new HashMap<Integer, IBluetoothStateChangeCallback>());
-
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-    static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
-    private static final String DOCK_ADDRESS_PATH = "/sys/class/switch/dock/bt_addr";
-    private static final String DOCK_PIN_PATH = "/sys/class/switch/dock/bt_pin";
-
-    private static final String SHARED_PREFERENCE_DOCK_ADDRESS = "dock_bluetooth_address";
-    private static final String SHARED_PREFERENCES_NAME = "bluetooth_service_settings";
-
-    private static final int MESSAGE_UUID_INTENT = 1;
-    private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 2;
-    private static final int MESSAGE_REMOVE_SERVICE_RECORD = 3;
-
-    private static final int RFCOMM_RECORD_REAPER = 10;
-    private static final int STATE_CHANGE_REAPER = 11;
-
-    // The time (in millisecs) to delay the pairing attempt after the first
-    // auto pairing attempt fails. We use an exponential delay with
-    // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
-    // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the max value.
-    private static final long INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 3000;
-    private static final long MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 12000;
-
-    // The timeout used to sent the UUIDs Intent
-    // This timeout should be greater than the page timeout
-    private static final int UUID_INTENT_DELAY = 6000;
-
-    /** Always retrieve RFCOMM channel for these SDP UUIDs */
-    private static final ParcelUuid[] RFCOMM_UUIDS = {
-            BluetoothUuid.Handsfree,
-            BluetoothUuid.HSP,
-            BluetoothUuid.ObexObjectPush };
-
-    private final BluetoothAdapterProperties mAdapterProperties;
-    private final BluetoothDeviceProperties mDeviceProperties;
-
-    private final HashMap<String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
-    private final ArrayList<String> mUuidIntentTracker;
-    private final HashMap<RemoteService, IBluetoothCallback> mUuidCallbackTracker;
-
-    private static class ServiceRecordClient {
-        int pid;
-        IBinder binder;
-        IBinder.DeathRecipient death;
-    }
-    private final HashMap<Integer, ServiceRecordClient> mServiceRecordToPid;
-
-    private final HashMap<String, BluetoothDeviceProfileState> mDeviceProfileState;
-    private final BluetoothProfileState mA2dpProfileState;
-    private final BluetoothProfileState mHfpProfileState;
-
-    private BluetoothA2dpService mA2dpService;
-    private final HashMap<String, Pair<byte[], byte[]>> mDeviceOobData;
-
-    private int mProfilesConnected = 0, mProfilesConnecting = 0, mProfilesDisconnecting = 0;
-
-    private static String mDockAddress;
-    private String mDockPin;
-
-    private boolean mAllowConnect = true;
-
-    private int mAdapterConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
-    private BluetoothPanProfileHandler mBluetoothPanProfileHandler;
-    private BluetoothInputProfileHandler mBluetoothInputProfileHandler;
-    private BluetoothHealthProfileHandler mBluetoothHealthProfileHandler;
-    private static final String INCOMING_CONNECTION_FILE =
-      "/data/misc/bluetooth/incoming_connection.conf";
-    private HashMap<String, Pair<Integer, String>> mIncomingConnections;
-    private HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState;
-
-    private static class RemoteService {
-        public String address;
-        public ParcelUuid uuid;
-        public RemoteService(String address, ParcelUuid uuid) {
-            this.address = address;
-            this.uuid = uuid;
-        }
-        @Override
-        public boolean equals(Object o) {
-            if (o instanceof RemoteService) {
-                RemoteService service = (RemoteService)o;
-                return address.equals(service.address) && uuid.equals(service.uuid);
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 1;
-            hash = hash * 31 + (address == null ? 0 : address.hashCode());
-            hash = hash * 31 + (uuid == null ? 0 : uuid.hashCode());
-            return hash;
-        }
-    }
-
-    static {
-        classInitNative();
-    }
-
-    public BluetoothService(Context context) {
-        mContext = context;
-
-        // Need to do this in place of:
-        // mBatteryStats = BatteryStatsService.getService();
-        // Since we can not import BatteryStatsService from here. This class really needs to be
-        // moved to java/services/com/android/server/
-        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
-
-        initializeNativeDataNative();
-
-        if (isEnabledNative() == 1) {
-            Log.w(TAG, "Bluetooth daemons already running - runtime restart? ");
-            disableNative();
-        }
-
-        mBondState = new BluetoothBondState(context, this);
-        mAdapterProperties = new BluetoothAdapterProperties(context, this);
-        mDeviceProperties = new BluetoothDeviceProperties(this);
-
-        mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
-        mDeviceOobData = new HashMap<String, Pair<byte[], byte[]>>();
-        mUuidIntentTracker = new ArrayList<String>();
-        mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
-        mServiceRecordToPid = new HashMap<Integer, ServiceRecordClient>();
-        mDeviceProfileState = new HashMap<String, BluetoothDeviceProfileState>();
-        mA2dpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.A2DP);
-        mHfpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HFP);
-
-        mHfpProfileState.start();
-        mA2dpProfileState.start();
-
-        IntentFilter filter = new IntentFilter();
-        registerForAirplaneMode(filter);
-
-        filter.addAction(Intent.ACTION_DOCK_EVENT);
-        mContext.registerReceiver(mReceiver, filter);
-        mBluetoothInputProfileHandler = BluetoothInputProfileHandler.getInstance(mContext, this);
-        mBluetoothPanProfileHandler = BluetoothPanProfileHandler.getInstance(mContext, this);
-        mBluetoothHealthProfileHandler = BluetoothHealthProfileHandler.getInstance(mContext, this);
-        mIncomingConnections = new HashMap<String, Pair<Integer, String>>();
-        mProfileConnectionState = new HashMap<Integer, Pair<Integer, Integer>>();
-    }
-
-    public static synchronized String readDockBluetoothAddress() {
-        if (mDockAddress != null) return mDockAddress;
-
-        BufferedInputStream file = null;
-        String dockAddress;
-        try {
-            file = new BufferedInputStream(new FileInputStream(DOCK_ADDRESS_PATH));
-            byte[] address = new byte[17];
-            file.read(address);
-            dockAddress = new String(address);
-            dockAddress = dockAddress.toUpperCase();
-            if (BluetoothAdapter.checkBluetoothAddress(dockAddress)) {
-                mDockAddress = dockAddress;
-                return mDockAddress;
-            } else {
-                Log.e(TAG, "CheckBluetoothAddress failed for car dock address: "
-                        + dockAddress);
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "FileNotFoundException while trying to read dock address");
-        } catch (IOException e) {
-            Log.e(TAG, "IOException while trying to read dock address");
-        } finally {
-            if (file != null) {
-                try {
-                    file.close();
-                } catch (IOException e) {
-                    // Ignore
-                }
-            }
-        }
-        mDockAddress = null;
-        return null;
-    }
-
-    private synchronized boolean writeDockPin() {
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new FileWriter(DOCK_PIN_PATH));
-
-            // Generate a random 4 digit pin between 0000 and 9999
-            // This is not truly random but good enough for our purposes.
-            int pin = (int) Math.floor(Math.random() * 10000);
-
-            mDockPin = String.format("%04d", pin);
-            out.write(mDockPin);
-            return true;
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "FileNotFoundException while trying to write dock pairing pin");
-        } catch (IOException e) {
-            Log.e(TAG, "IOException while while trying to write dock pairing pin");
-        } finally {
-            if (out != null) {
-                try {
-                    out.close();
-                } catch (IOException e) {
-                    // Ignore
-                }
-            }
-        }
-        mDockPin = null;
-        return false;
-    }
-
-    /*package*/ synchronized String getDockPin() {
-        return mDockPin;
-    }
-
-    public synchronized void initAfterRegistration() {
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);
-        mBluetoothState.start();
-        if (mContext.getResources().getBoolean
-            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
-        }
-        mEventLoop = mBluetoothState.getBluetoothEventLoop();
-    }
-
-    public synchronized void initAfterA2dpRegistration() {
-        mEventLoop.getProfileProxy();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        mContext.unregisterReceiver(mReceiver);
-        try {
-            cleanupNativeDataNative();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    public boolean isEnabled() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return isEnabledInternal();
-    }
-
-    private boolean isEnabledInternal() {
-        return (getBluetoothStateInternal() == BluetoothAdapter.STATE_ON);
-    }
-
-    public int getBluetoothState() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return getBluetoothStateInternal();
-    }
-
-    int getBluetoothStateInternal() {
-        return mBluetoothState.getBluetoothAdapterState();
-    }
-
-    /**
-     * Bring down bluetooth and disable BT in settings. Returns true on success.
-     */
-    public boolean disable() {
-        return disable(true);
-    }
-
-    /**
-     * Bring down bluetooth. Returns true on success.
-     *
-     * @param saveSetting If true, persist the new setting
-     */
-    public synchronized boolean disable(boolean saveSetting) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
-
-        int adapterState = getBluetoothStateInternal();
-
-        switch (adapterState) {
-        case BluetoothAdapter.STATE_OFF:
-            return true;
-        case BluetoothAdapter.STATE_ON:
-            break;
-        default:
-            return false;
-        }
-
-        mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_OFF, saveSetting);
-        return true;
-    }
-
-    synchronized void disconnectDevices() {
-        // Disconnect devices handled by BluetoothService.
-        for (BluetoothDevice device: getConnectedInputDevices()) {
-            disconnectInputDevice(device);
-        }
-
-        for (BluetoothDevice device: getConnectedPanDevices()) {
-            disconnectPanDevice(device);
-        }
-    }
-
-    /**
-     * The Bluetooth has been turned off, but hot. Do bonding, profile cleanup
-     */
-    synchronized void finishDisable() {
-        // mark in progress bondings as cancelled
-        for (String address : mBondState.listInState(BluetoothDevice.BOND_BONDING)) {
-            mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
-                                    BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
-        }
-
-        // Stop the profile state machine for bonded devices.
-        for (String address : mBondState.listInState(BluetoothDevice.BOND_BONDED)) {
-            removeProfileState(address);
-        }
-
-        // update mode
-        Intent intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-        intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.SCAN_MODE_NONE);
-        mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-    }
-
-    /**
-     * Local clean up after broadcasting STATE_OFF intent
-     */
-    synchronized void cleanupAfterFinishDisable() {
-        mAdapterProperties.clear();
-
-        for (Integer srHandle : mServiceRecordToPid.keySet()) {
-            removeServiceRecordNative(srHandle);
-        }
-        mServiceRecordToPid.clear();
-
-        mProfilesConnected = 0;
-        mProfilesConnecting = 0;
-        mProfilesDisconnecting = 0;
-        mAdapterConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
-        mAdapterUuids = null;
-        mAdapterSdpHandles = null;
-
-        // Log bluetooth off to battery stats.
-        long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteBluetoothOff();
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /**
-     * power off Bluetooth
-     */
-    synchronized void shutoffBluetooth() {
-        if (mAdapterSdpHandles != null) removeReservedServiceRecordsNative(mAdapterSdpHandles);
-        setBluetoothTetheringNative(false, BluetoothPanProfileHandler.NAP_ROLE,
-                BluetoothPanProfileHandler.NAP_BRIDGE);
-        tearDownNativeDataNative();
-    }
-
-    /**
-     * Data clean up after Bluetooth shutoff
-     */
-    synchronized void cleanNativeAfterShutoffBluetooth() {
-        // Ths method is called after shutdown of event loop in the Bluetooth shut down
-        // procedure
-
-        // the adapter property could be changed before event loop is stoped, clear it again
-        mAdapterProperties.clear();
-        disableNative();
-    }
-
-    /** Bring up BT and persist BT on in settings */
-    public boolean enable() {
-        return enable(true, true);
-    }
-
-    /**
-     * Enable this Bluetooth device, asynchronously.
-     * This turns on/off the underlying hardware.
-     *
-     * @param saveSetting If true, persist the new state of BT in settings
-     * @param allowConnect If true, auto-connects device when BT is turned on
-     *                     and allows incoming A2DP/HSP connections
-     * @return True on success (so far)
-     */
-    public synchronized boolean enable(boolean saveSetting, boolean allowConnect) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-
-        // Airplane mode can prevent Bluetooth radio from being turned on.
-        if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) {
-            return false;
-        }
-        mAllowConnect = allowConnect;
-        mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON, saveSetting);
-        return true;
-    }
-
-    /**
-     * Enable this Bluetooth device, asynchronously, but does not
-     * auto-connect devices. In this state the Bluetooth adapter
-     * also does not allow incoming A2DP/HSP connections (that
-     * must go through this service), but does allow communication
-     * on RFCOMM sockets implemented outside of this service (ie BTOPP).
-     * This method is used to temporarily enable Bluetooth
-     * for data transfer, without changing
-     *
-     * This turns on/off the underlying hardware.
-     *
-     * @return True on success (so far)
-     */
-    public boolean enableNoAutoConnect() {
-        return enable(false, false);
-    }
-
-    /**
-     * Turn on Bluetooth Module, Load firmware, and do all the preparation
-     * needed to get the Bluetooth Module ready but keep it not discoverable
-     * and not connectable.
-     */
-    /* package */ synchronized boolean prepareBluetooth() {
-        if (!setupNativeDataNative()) {
-            return false;
-        }
-        switchConnectable(false);
-
-        // Bluetooth stack needs a small delay here before adding
-        // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs
-        try {
-            Thread.sleep(50);
-        } catch (InterruptedException e) {}
-        updateSdpRecords();
-        return true;
-    }
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MESSAGE_UUID_INTENT:
-                String address = (String)msg.obj;
-                if (address != null) {
-                    sendUuidIntent(address);
-                    makeServiceChannelCallbacks(address);
-                }
-                break;
-            case MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
-                address = (String)msg.obj;
-                if (address == null) return;
-                int attempt = mBondState.getAttempt(address);
-
-                // Try only if attemps are in progress and cap it 2 attempts
-                // The 2 attempts cap is a fail safe if the stack returns
-                // an incorrect error code for bonding failures and if the pin
-                // is entered wrongly twice we should abort.
-                if (attempt > 0 && attempt <= 2) {
-                    mBondState.attempt(address);
-                    createBond(address);
-                    return;
-                }
-                if (attempt > 0) mBondState.clearPinAttempts(address);
-                break;
-            case MESSAGE_REMOVE_SERVICE_RECORD:
-                Pair<Integer, Integer> pair = (Pair<Integer, Integer>) msg.obj;
-                checkAndRemoveRecord(pair.first, pair.second);
-                break;
-            }
-        }
-    };
-
-    private synchronized void addReservedSdpRecords(final ArrayList<ParcelUuid> uuids) {
-        //Register SDP records.
-        int[] svcIdentifiers = new int[uuids.size()];
-        for (int i = 0; i < uuids.size(); i++) {
-            svcIdentifiers[i] = BluetoothUuid.getServiceIdentifierFromParcelUuid(uuids.get(i));
-        }
-        mAdapterSdpHandles = addReservedServiceRecordsNative(svcIdentifiers);
-    }
-
-    private synchronized void updateSdpRecords() {
-        ArrayList<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
-
-        Resources R = mContext.getResources();
-
-        // Add the default records
-        if (R.getBoolean(com.android.internal.R.bool.config_bluetooth_default_profiles)) {
-            uuids.add(BluetoothUuid.HSP_AG);
-            uuids.add(BluetoothUuid.ObexObjectPush);
-        }
-
-        if (R.getBoolean(com.android.internal.R.bool.config_voice_capable)) {
-            uuids.add(BluetoothUuid.Handsfree_AG);
-            uuids.add(BluetoothUuid.PBAP_PSE);
-        }
-
-        // Add SDP records for profiles maintained by Android userspace
-        addReservedSdpRecords(uuids);
-
-        // Bluetooth stack need some a small delay here before adding more
-        // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs
-        try {
-            Thread.sleep(50);
-        } catch (InterruptedException e) {}
-
-        if (R.getBoolean(com.android.internal.R.bool.config_bluetooth_default_profiles)) {
-            // Enable profiles maintained by Bluez userspace.
-            setBluetoothTetheringNative(true, BluetoothPanProfileHandler.NAP_ROLE,
-                   BluetoothPanProfileHandler.NAP_BRIDGE);
-
-            // Add SDP records for profiles maintained by Bluez userspace
-            uuids.add(BluetoothUuid.AudioSource);
-            uuids.add(BluetoothUuid.AvrcpTarget);
-            uuids.add(BluetoothUuid.NAP);
-        }
-
-        // Cannot cast uuids.toArray directly since ParcelUuid is parcelable
-        mAdapterUuids = new ParcelUuid[uuids.size()];
-        for (int i = 0; i < uuids.size(); i++) {
-            mAdapterUuids[i] = uuids.get(i);
-        }
-    }
-
-    /**
-     * This function is called from Bluetooth Event Loop when onPropertyChanged
-     * for adapter comes in with UUID property.
-     * @param uuidsThe uuids of adapter as reported by Bluez.
-     */
-    /*package*/ synchronized void updateBluetoothState(String uuids) {
-        ParcelUuid[] adapterUuids = convertStringToParcelUuid(uuids);
-
-        if (mAdapterUuids != null &&
-            BluetoothUuid.containsAllUuids(adapterUuids, mAdapterUuids)) {
-            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.SERVICE_RECORD_LOADED);
-        }
-    }
-
-    /**
-     * This method is called immediately before Bluetooth module is turned on after
-     * the adapter became pariable.
-     * It inits bond state and profile state before STATE_ON intent is broadcasted.
-     */
-    /*package*/ void initBluetoothAfterTurningOn() {
-        String discoverable = getProperty("Discoverable", false);
-        String timeout = getProperty("DiscoverableTimeout", false);
-        if (timeout == null) {
-            Log.w(TAG, "Null DiscoverableTimeout property");
-            // assign a number, anything not 0
-            timeout = "1";
-        }
-        if (discoverable.equals("true") && Integer.valueOf(timeout) != 0) {
-            setAdapterPropertyBooleanNative("Discoverable", 0);
-        }
-        mBondState.initBondState();
-        initProfileState();
-        getProfileProxy();
-    }
-
-    /**
-     * This method is called immediately after Bluetooth module is turned on.
-     * It starts auto-connection and places bluetooth on sign onto the battery
-     * stats
-     */
-    /*package*/ void runBluetooth() {
-        autoConnect();
-
-        // Log bluetooth on to battery stats.
-        long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteBluetoothOn();
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /*package*/ synchronized boolean attemptAutoPair(String address) {
-        if (!mBondState.hasAutoPairingFailed(address) &&
-                !mBondState.isAutoPairingBlacklisted(address)) {
-            mBondState.attempt(address);
-            setPin(address, BluetoothDevice.convertPinToBytes("0000"));
-            return true;
-        }
-        return false;
-    }
-
-    /*package*/ synchronized boolean isFixedPinZerosAutoPairKeyboard(String address) {
-        // Check for keyboards which have fixed PIN 0000 as the pairing pin
-        return mBondState.isFixedPinZerosAutoPairKeyboard(address);
-    }
-
-    /*package*/ synchronized void onCreatePairedDeviceResult(String address, int result) {
-        if (result == BluetoothDevice.BOND_SUCCESS) {
-            setBondState(address, BluetoothDevice.BOND_BONDED);
-            if (mBondState.isAutoPairingAttemptsInProgress(address)) {
-                mBondState.clearPinAttempts(address);
-            }
-        } else if (result == BluetoothDevice.UNBOND_REASON_AUTH_FAILED &&
-                mBondState.getAttempt(address) == 1) {
-            mBondState.addAutoPairingFailure(address);
-            pairingAttempt(address, result);
-        } else if (result == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN &&
-              mBondState.isAutoPairingAttemptsInProgress(address)) {
-            pairingAttempt(address, result);
-        } else {
-            setBondState(address, BluetoothDevice.BOND_NONE, result);
-            if (mBondState.isAutoPairingAttemptsInProgress(address)) {
-                mBondState.clearPinAttempts(address);
-            }
-        }
-    }
-
-    /*package*/ synchronized String getPendingOutgoingBonding() {
-        return mBondState.getPendingOutgoingBonding();
-    }
-
-    private void pairingAttempt(String address, int result) {
-        // This happens when our initial guess of "0000" as the pass key
-        // fails. Try to create the bond again and display the pin dialog
-        // to the user. Use back-off while posting the delayed
-        // message. The initial value is
-        // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY and the max value is
-        // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY. If the max value is
-        // reached, display an error to the user.
-        int attempt = mBondState.getAttempt(address);
-        if (attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY >
-                    MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) {
-            mBondState.clearPinAttempts(address);
-            setBondState(address, BluetoothDevice.BOND_NONE, result);
-            return;
-        }
-
-        Message message = mHandler.obtainMessage(MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
-        message.obj = address;
-        boolean postResult =  mHandler.sendMessageDelayed(message,
-                                        attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
-        if (!postResult) {
-            mBondState.clearPinAttempts(address);
-            setBondState(address,
-                    BluetoothDevice.BOND_NONE, result);
-            return;
-        }
-    }
-
-    /*package*/ BluetoothDevice getRemoteDevice(String address) {
-        return mAdapter.getRemoteDevice(address);
-    }
-
-    private static String toBondStateString(int bondState) {
-        switch (bondState) {
-        case BluetoothDevice.BOND_NONE:
-            return "not bonded";
-        case BluetoothDevice.BOND_BONDING:
-            return "bonding";
-        case BluetoothDevice.BOND_BONDED:
-            return "bonded";
-        default:
-            return "??????";
-        }
-    }
-
-    public synchronized boolean setName(String name) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (name == null) {
-            return false;
-        }
-        return setPropertyString("Name", name);
-    }
-
-    //TODO(): setPropertyString, setPropertyInteger, setPropertyBoolean
-    // Either have a single property function with Object as the parameter
-    // or have a function for each property and then obfuscate in the JNI layer.
-    // The following looks dirty.
-    private boolean setPropertyString(String key, String value) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return false;
-        return setAdapterPropertyStringNative(key, value);
-    }
-
-    private boolean setPropertyInteger(String key, int value) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return false;
-        return setAdapterPropertyIntegerNative(key, value);
-    }
-
-    private boolean setPropertyBoolean(String key, boolean value) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return false;
-        return setAdapterPropertyBooleanNative(key, value ? 1 : 0);
-    }
-
-    /**
-     * Set the discoverability window for the device.  A timeout of zero
-     * makes the device permanently discoverable (if the device is
-     * discoverable).  Setting the timeout to a nonzero value does not make
-     * a device discoverable; you need to call setMode() to make the device
-     * explicitly discoverable.
-     *
-     * @param timeout The discoverable timeout in seconds.
-     */
-    public synchronized boolean setDiscoverableTimeout(int timeout) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        return setPropertyInteger("DiscoverableTimeout", timeout);
-    }
-
-    public synchronized boolean setScanMode(int mode, int duration) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
-                                                "Need WRITE_SECURE_SETTINGS permission");
-        boolean pairable;
-        boolean discoverable;
-
-        switch (mode) {
-        case BluetoothAdapter.SCAN_MODE_NONE:
-            pairable = false;
-            discoverable = false;
-            break;
-        case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
-            pairable = true;
-            discoverable = false;
-            break;
-        case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
-            pairable = true;
-            discoverable = true;
-            if (DBG) Log.d(TAG, "BT Discoverable for " + duration + " seconds");
-            break;
-        default:
-            Log.w(TAG, "Requested invalid scan mode " + mode);
-            return false;
-        }
-
-        setPropertyBoolean("Discoverable", discoverable);
-        setPropertyBoolean("Pairable", pairable);
-        return true;
-    }
-
-    /**
-     * @param on true set the local Bluetooth module to be connectable
-     *                The dicoverability is recovered to what it was before
-     *                switchConnectable(false) call
-     *           false set the local Bluetooth module to be not connectable
-     *                 and not dicoverable
-     */
-    /*package*/ synchronized void switchConnectable(boolean on) {
-        setAdapterPropertyBooleanNative("Powered", on ? 1 : 0);
-    }
-
-    /*package*/ synchronized void setPairable() {
-        String pairableString = getProperty("Pairable", false);
-        if (pairableString == null) {
-            Log.e(TAG, "null pairableString");
-            return;
-        }
-        if (pairableString.equals("false")) {
-            setAdapterPropertyBooleanNative("Pairable", 1);
-        }
-    }
-
-    /*package*/ String getProperty(String name, boolean checkState) {
-        // If checkState is false, check if the event loop is running.
-        // before making the call to Bluez
-        if (checkState) {
-            if (!isEnabledInternal()) return null;
-        } else if (!mEventLoop.isEventLoopRunning()) {
-            return null;
-        }
-
-        return mAdapterProperties.getProperty(name);
-    }
-
-    BluetoothAdapterProperties getAdapterProperties() {
-        return mAdapterProperties;
-    }
-
-    BluetoothDeviceProperties getDeviceProperties() {
-        return mDeviceProperties;
-    }
-
-    boolean isRemoteDeviceInCache(String address) {
-        return mDeviceProperties.isInCache(address);
-    }
-
-    void setRemoteDeviceProperty(String address, String name, String value) {
-        mDeviceProperties.setProperty(address, name, value);
-    }
-
-    void updateRemoteDevicePropertiesCache(String address) {
-        mDeviceProperties.updateCache(address);
-    }
-
-    public synchronized String getAddress() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        // Don't check state since we want to provide address, even if BT is off
-        return getProperty("Address", false);
-    }
-
-    public synchronized String getName() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        // Don't check state since we want to provide name, even if BT is off
-        return getProperty("Name", false);
-    }
-
-    public ParcelUuid[] getUuids() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        String value =  getProperty("UUIDs", true);
-        if (value == null) return null;
-        return convertStringToParcelUuid(value);
-    }
-
-    private ParcelUuid[] convertStringToParcelUuid(String value) {
-        String[] uuidStrings = null;
-        // The UUIDs are stored as a "," separated string.
-        uuidStrings = value.split(",");
-        ParcelUuid[] uuids = new ParcelUuid[uuidStrings.length];
-
-        for (int i = 0; i < uuidStrings.length; i++) {
-            uuids[i] = ParcelUuid.fromString(uuidStrings[i]);
-        }
-        return uuids;
-    }
-
-    /**
-     * Returns the user-friendly name of a remote device.  This value is
-     * returned from our local cache, which is updated when onPropertyChange
-     * event is received.
-     * Do not expect to retrieve the updated remote name immediately after
-     * changing the name on the remote device.
-     *
-     * @param address Bluetooth address of remote device.
-     *
-     * @return The user-friendly name of the specified remote device.
-     */
-    public synchronized String getRemoteName(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return null;
-        }
-        return mDeviceProperties.getProperty(address, "Name");
-    }
-
-    /**
-     * Returns alias of a remote device.  This value is returned from our
-     * local cache, which is updated when onPropertyChange event is received.
-     *
-     * @param address Bluetooth address of remote device.
-     *
-     * @return The alias of the specified remote device.
-     */
-    public synchronized String getRemoteAlias(String address) {
-
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return null;
-        }
-        return mDeviceProperties.getProperty(address, "Alias");
-    }
-
-    /**
-     * Set the alias of a remote device.
-     *
-     * @param address Bluetooth address of remote device.
-     * @param alias new alias to change to
-     * @return true on success, false on error
-     */
-    public synchronized boolean setRemoteAlias(String address, String alias) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-
-        return setDevicePropertyStringNative(getObjectPathFromAddress(address),
-                                             "Alias", alias);
-    }
-
-    /**
-     * Get the discoverability window for the device.  A timeout of zero
-     * means that the device is permanently discoverable (if the device is
-     * in the discoverable mode).
-     *
-     * @return The discoverability window of the device, in seconds.  A negative
-     *         value indicates an error.
-     */
-    public int getDiscoverableTimeout() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        String timeout = getProperty("DiscoverableTimeout", true);
-        if (timeout != null)
-           return Integer.valueOf(timeout);
-        else
-            return -1;
-    }
-
-    public int getScanMode() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal())
-            return BluetoothAdapter.SCAN_MODE_NONE;
-
-        boolean pairable = getProperty("Pairable", true).equals("true");
-        boolean discoverable = getProperty("Discoverable", true).equals("true");
-        return bluezStringToScanMode (pairable, discoverable);
-    }
-
-    public synchronized boolean startDiscovery() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        return startDiscoveryNative();
-    }
-
-    public synchronized boolean cancelDiscovery() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        return stopDiscoveryNative();
-    }
-
-    public boolean isDiscovering() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-
-        String discoveringProperty = getProperty("Discovering", false);
-        if (discoveringProperty == null) {
-            return false;
-        }
-
-        return discoveringProperty.equals("true");
-    }
-
-    private boolean isBondingFeasible(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        address = address.toUpperCase();
-
-        if (mBondState.getPendingOutgoingBonding() != null) {
-            Log.d(TAG, "Ignoring createBond(): another device is bonding");
-            // a different device is currently bonding, fail
-            return false;
-        }
-
-        // Check for bond state only if we are not performing auto
-        // pairing exponential back-off attempts.
-        if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
-                mBondState.getBondState(address) != BluetoothDevice.BOND_NONE) {
-            Log.d(TAG, "Ignoring createBond(): this device is already bonding or bonded");
-            return false;
-        }
-
-        if (address.equals(mDockAddress)) {
-            if (!writeDockPin()) {
-                Log.e(TAG, "Error while writing Pin for the dock");
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public synchronized boolean createBond(String address) {
-        if (!isBondingFeasible(address)) return false;
-
-        if (!createPairedDeviceNative(address, 60000  /*1 minute*/ )) {
-            return false;
-        }
-
-        mBondState.setPendingOutgoingBonding(address);
-        mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
-
-        return true;
-    }
-
-    public synchronized boolean createBondOutOfBand(String address, byte[] hash,
-                                                    byte[] randomizer) {
-        if (!isBondingFeasible(address)) return false;
-
-        if (!createPairedDeviceOutOfBandNative(address, 60000 /* 1 minute */)) {
-            return false;
-        }
-
-        setDeviceOutOfBandData(address, hash, randomizer);
-        mBondState.setPendingOutgoingBonding(address);
-        mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
-
-        return true;
-    }
-
-    public synchronized boolean setDeviceOutOfBandData(String address, byte[] hash,
-            byte[] randomizer) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        Pair <byte[], byte[]> value = new Pair<byte[], byte[]>(hash, randomizer);
-
-        if (DBG) {
-            Log.d(TAG, "Setting out of band data for: " + address + ":" +
-                  Arrays.toString(hash) + ":" + Arrays.toString(randomizer));
-        }
-
-        mDeviceOobData.put(address, value);
-        return true;
-    }
-
-    Pair<byte[], byte[]> getDeviceOutOfBandData(BluetoothDevice device) {
-        return mDeviceOobData.get(device.getAddress());
-    }
-
-
-    public synchronized byte[] readOutOfBandData() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                                                "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return null;
-
-        return readAdapterOutOfBandDataNative();
-    }
-
-    public synchronized boolean cancelBondProcess(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        address = address.toUpperCase();
-        if (mBondState.getBondState(address) != BluetoothDevice.BOND_BONDING) {
-            return false;
-        }
-
-        mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
-                                BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
-        cancelDeviceCreationNative(address);
-        return true;
-    }
-
-    public synchronized boolean removeBond(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            state.sendMessage(BluetoothDeviceProfileState.UNPAIR);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public synchronized boolean removeBondInternal(String address) {
-        // Unset the trusted device state and then unpair
-        setTrust(address, false);
-        return removeDeviceNative(getObjectPathFromAddress(address));
-    }
-
-    public synchronized String[] listBonds() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return mBondState.listInState(BluetoothDevice.BOND_BONDED);
-    }
-
-    /*package*/ synchronized String[] listInState(int state) {
-      return mBondState.listInState(state);
-    }
-
-    public synchronized int getBondState(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return BluetoothDevice.ERROR;
-        }
-        return mBondState.getBondState(address.toUpperCase());
-    }
-
-    /*package*/ synchronized boolean setBondState(String address, int state) {
-        return setBondState(address, state, 0);
-    }
-
-    /*package*/ synchronized boolean setBondState(String address, int state, int reason) {
-        mBondState.setBondState(address.toUpperCase(), state, reason);
-        return true;
-    }
-
-    public synchronized boolean isBluetoothDock(String address) {
-        SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-
-        return sp.contains(SHARED_PREFERENCE_DOCK_ADDRESS + address);
-    }
-
-    /*package*/ String[] getRemoteDeviceProperties(String address) {
-        if (!isEnabledInternal()) return null;
-
-        String objectPath = getObjectPathFromAddress(address);
-        return (String [])getDevicePropertiesNative(objectPath);
-    }
-
-    /**
-     * Sets the remote device trust state.
-     *
-     * @return boolean to indicate operation success or fail
-     */
-    public synchronized boolean setTrust(String address, boolean value) {
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                    "Need BLUETOOTH_ADMIN permission");
-            return false;
-        }
-
-        if (!isEnabledInternal()) return false;
-
-        return setDevicePropertyBooleanNative(
-                getObjectPathFromAddress(address), "Trusted", value ? 1 : 0);
-    }
-
-    /**
-     * Gets the remote device trust state as boolean.
-     * Note: this value may be
-     * retrieved from cache if we retrieved the data before *
-     *
-     * @return boolean to indicate trusted or untrusted state
-     */
-    public synchronized boolean getTrustState(String address) {
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            return false;
-        }
-
-        String val = mDeviceProperties.getProperty(address, "Trusted");
-        if (val == null) {
-            return false;
-        } else {
-            return val.equals("true");
-        }
-    }
-
-    /**
-     * Gets the remote major, minor classes encoded as a 32-bit
-     * integer.
-     *
-     * Note: this value is retrieved from cache, because we get it during
-     *       remote-device discovery.
-     *
-     * @return 32-bit integer encoding the remote major, minor, and service
-     *         classes.
-     */
-    public synchronized int getRemoteClass(String address) {
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            return BluetoothClass.ERROR;
-        }
-        String val = mDeviceProperties.getProperty(address, "Class");
-        if (val == null)
-            return BluetoothClass.ERROR;
-        else {
-            return Integer.valueOf(val);
-        }
-    }
-
-
-    /**
-     * Gets the UUIDs supported by the remote device
-     *
-     * @return array of 128bit ParcelUuids
-     */
-    public synchronized ParcelUuid[] getRemoteUuids(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return null;
-        }
-        return getUuidFromCache(address);
-    }
-
-    ParcelUuid[] getUuidFromCache(String address) {
-        String value = mDeviceProperties.getProperty(address, "UUIDs");
-        if (value == null) return null;
-
-        String[] uuidStrings = null;
-        // The UUIDs are stored as a "," separated string.
-        uuidStrings = value.split(",");
-        ParcelUuid[] uuids = new ParcelUuid[uuidStrings.length];
-
-        for (int i = 0; i < uuidStrings.length; i++) {
-            uuids[i] = ParcelUuid.fromString(uuidStrings[i]);
-        }
-        return uuids;
-    }
-
-    /**
-     * Connect and fetch new UUID's using SDP.
-     * The UUID's found are broadcast as intents.
-     * Optionally takes a uuid and callback to fetch the RFCOMM channel for the
-     * a given uuid.
-     * TODO: Don't wait UUID_INTENT_DELAY to broadcast UUID intents on success
-     * TODO: Don't wait UUID_INTENT_DELAY to handle the failure case for
-     * callback and broadcast intents.
-     */
-    public synchronized boolean fetchRemoteUuids(String address, ParcelUuid uuid,
-            IBluetoothCallback callback) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return false;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-
-        RemoteService service = new RemoteService(address, uuid);
-        if (uuid != null && mUuidCallbackTracker.get(service) != null) {
-            // An SDP query for this address & uuid is already in progress
-            // Do not add this callback for the uuid
-            return false;
-        }
-
-        if (mUuidIntentTracker.contains(address)) {
-            // An SDP query for this address is already in progress
-            // Add this uuid onto the in-progress SDP query
-            if (uuid != null) {
-                mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
-            }
-            return true;
-        }
-
-        // If the device is already created, we will
-        // do the SDP on the callback of createDeviceNative.
-        boolean ret= createDeviceNative(address);
-
-        mUuidIntentTracker.add(address);
-        if (uuid != null) {
-            mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
-        }
-
-        Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
-        message.obj = address;
-        mHandler.sendMessageDelayed(message, UUID_INTENT_DELAY);
-        return ret;
-    }
-
-    /**
-     * Gets the rfcomm channel associated with the UUID.
-     * Pulls records from the cache only.
-     *
-     * @param address Address of the remote device
-     * @param uuid ParcelUuid of the service attribute
-     *
-     * @return rfcomm channel associated with the service attribute
-     *         -1 on error
-     */
-    public int getRemoteServiceChannel(String address, ParcelUuid uuid) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return -1;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return BluetoothDevice.ERROR;
-        }
-        // Check if we are recovering from a crash.
-        if (mDeviceProperties.isEmpty()) {
-            if (mDeviceProperties.updateCache(address) == null)
-                return -1;
-        }
-
-        Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address);
-        if (value != null && value.containsKey(uuid))
-            return value.get(uuid);
-        return -1;
-    }
-
-    public synchronized boolean setPin(String address, byte[] pin) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (pin == null || pin.length <= 0 || pin.length > 16 ||
-            !BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        address = address.toUpperCase();
-        Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
-        if (data == null) {
-            Log.w(TAG, "setPin(" + address + ") called but no native data available, " +
-                  "ignoring. Maybe the PasskeyAgent Request was cancelled by the remote device" +
-                  " or by bluez.\n");
-            return false;
-        }
-        // bluez API wants pin as a string
-        String pinString;
-        try {
-            pinString = new String(pin, "UTF8");
-        } catch (UnsupportedEncodingException uee) {
-            Log.e(TAG, "UTF8 not supported?!?");
-            return false;
-        }
-        return setPinNative(address, pinString, data.intValue());
-    }
-
-    public synchronized boolean setPasskey(String address, int passkey) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (passkey < 0 || passkey > 999999 || !BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        address = address.toUpperCase();
-        Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
-        if (data == null) {
-            Log.w(TAG, "setPasskey(" + address + ") called but no native data available, " +
-                  "ignoring. Maybe the PasskeyAgent Request was cancelled by the remote device" +
-                  " or by bluez.\n");
-            return false;
-        }
-        return setPasskeyNative(address, passkey, data.intValue());
-    }
-
-    public synchronized boolean setPairingConfirmation(String address, boolean confirm) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        address = address.toUpperCase();
-        Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
-        if (data == null) {
-            Log.w(TAG, "setPasskey(" + address + ") called but no native data available, " +
-                  "ignoring. Maybe the PasskeyAgent Request was cancelled by the remote device" +
-                  " or by bluez.\n");
-            return false;
-        }
-        return setPairingConfirmationNative(address, confirm, data.intValue());
-    }
-
-    public synchronized boolean setRemoteOutOfBandData(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-        address = address.toUpperCase();
-        Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
-        if (data == null) {
-            Log.w(TAG, "setRemoteOobData(" + address + ") called but no native data available, " +
-                  "ignoring. Maybe the PasskeyAgent Request was cancelled by the remote device" +
-                  " or by bluez.\n");
-            return false;
-        }
-
-        Pair<byte[], byte[]> val = mDeviceOobData.get(address);
-        byte[] hash, randomizer;
-        if (val == null) {
-            // TODO: check what should be passed in this case.
-            hash = new byte[16];
-            randomizer = new byte[16];
-        } else {
-            hash = val.first;
-            randomizer = val.second;
-        }
-        return setRemoteOutOfBandDataNative(address, hash, randomizer, data.intValue());
-    }
-
-    public synchronized boolean cancelPairingUserInput(String address) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        if (!isEnabledInternal()) return false;
-
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-        mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
-                BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
-        address = address.toUpperCase();
-        Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
-        if (data == null) {
-            Log.w(TAG, "cancelUserInputNative(" + address + ") called but no native data " +
-                "available, ignoring. Maybe the PasskeyAgent Request was already cancelled " +
-                "by the remote or by bluez.\n");
-            return false;
-        }
-        return cancelPairingUserInputNative(address, data.intValue());
-    }
-
-    /*package*/ void updateDeviceServiceChannelCache(String address) {
-        if (DBG) Log.d(TAG, "updateDeviceServiceChannelCache(" + address + ")");
-
-        // We are storing the rfcomm channel numbers only for the uuids
-        // we are interested in.
-        ParcelUuid[] deviceUuids = getRemoteUuids(address);
-
-        ArrayList<ParcelUuid> applicationUuids = new ArrayList<ParcelUuid>();
-
-        synchronized (this) {
-            for (RemoteService service : mUuidCallbackTracker.keySet()) {
-                if (service.address.equals(address)) {
-                    applicationUuids.add(service.uuid);
-                }
-            }
-        }
-
-        Map <ParcelUuid, Integer> uuidToChannelMap = new HashMap<ParcelUuid, Integer>();
-
-        // Retrieve RFCOMM channel for default uuids
-        for (ParcelUuid uuid : RFCOMM_UUIDS) {
-            if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
-                int channel = getDeviceServiceChannelForUuid(address, uuid);
-                uuidToChannelMap.put(uuid, channel);
-                if (DBG) Log.d(TAG, "\tuuid(system): " + uuid + " " + channel);
-            }
-        }
-        // Retrieve RFCOMM channel for application requested uuids
-        for (ParcelUuid uuid : applicationUuids) {
-            if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
-                int channel = getDeviceServiceChannelForUuid(address, uuid);
-                uuidToChannelMap.put(uuid, channel);
-                if (DBG) Log.d(TAG, "\tuuid(application): " + uuid + " " + channel);
-            }
-        }
-
-        synchronized (this) {
-            // Make application callbacks
-            for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
-                    iter.hasNext();) {
-                RemoteService service = iter.next();
-                if (service.address.equals(address)) {
-                    if (uuidToChannelMap.containsKey(service.uuid)) {
-                        int channel = uuidToChannelMap.get(service.uuid);
-
-                        if (DBG) Log.d(TAG, "Making callback for " + service.uuid +
-                                    " with result " + channel);
-                        IBluetoothCallback callback = mUuidCallbackTracker.get(service);
-                        if (callback != null) {
-                            try {
-                                callback.onRfcommChannelFound(channel);
-                            } catch (RemoteException e) {Log.e(TAG, "", e);}
-                        }
-
-                        iter.remove();
-                    }
-                }
-            }
-
-            // Update cache
-            mDeviceServiceChannelCache.put(address, uuidToChannelMap);
-        }
-    }
-
-    private int getDeviceServiceChannelForUuid(String address,
-            ParcelUuid uuid) {
-        return getDeviceServiceChannelNative(getObjectPathFromAddress(address),
-                uuid.toString(), 0x0004);
-    }
-
-    /**
-     * b is a handle to a Binder instance, so that this service can be notified
-     * for Applications that terminate unexpectedly, to clean there service
-     * records
-     */
-    public synchronized int addRfcommServiceRecord(String serviceName, ParcelUuid uuid,
-            int channel, IBinder b) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!isEnabledInternal()) return -1;
-
-        if (serviceName == null || uuid == null || channel < 1 ||
-                channel > BluetoothSocket.MAX_RFCOMM_CHANNEL) {
-            return -1;
-        }
-        if (BluetoothUuid.isUuidPresent(BluetoothUuid.RESERVED_UUIDS, uuid)) {
-            Log.w(TAG, "Attempted to register a reserved UUID: " + uuid);
-            return -1;
-        }
-        int handle = addRfcommServiceRecordNative(serviceName,
-                uuid.getUuid().getMostSignificantBits(), uuid.getUuid().getLeastSignificantBits(),
-                (short)channel);
-        if (DBG) Log.d(TAG, "new handle " + Integer.toHexString(handle));
-        if (handle == -1) {
-            return -1;
-        }
-
-        ServiceRecordClient client = new ServiceRecordClient();
-        client.pid = Binder.getCallingPid();
-        client.binder = b;
-        client.death = new Reaper(handle, client.pid, RFCOMM_RECORD_REAPER);
-        mServiceRecordToPid.put(new Integer(handle), client);
-        try {
-            b.linkToDeath(client.death, 0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "", e);
-            client.death = null;
-        }
-        return handle;
-    }
-
-    public void removeServiceRecord(int handle) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                                                "Need BLUETOOTH permission");
-        // Since this is a binder call check if Bluetooth is off
-        if (getBluetoothStateInternal() == BluetoothAdapter.STATE_OFF) return;
-        Message message = mHandler.obtainMessage(MESSAGE_REMOVE_SERVICE_RECORD);
-        message.obj = new Pair<Integer, Integer>(handle, Binder.getCallingPid());
-        mHandler.sendMessage(message);
-    }
-
-    private synchronized void checkAndRemoveRecord(int handle, int pid) {
-        ServiceRecordClient client = mServiceRecordToPid.get(handle);
-        if (client != null && pid == client.pid) {
-            if (DBG) Log.d(TAG, "Removing service record " +
-                Integer.toHexString(handle) + " for pid " + pid);
-
-            if (client.death != null) {
-                client.binder.unlinkToDeath(client.death, 0);
-            }
-
-            mServiceRecordToPid.remove(handle);
-            removeServiceRecordNative(handle);
-        }
-    }
-
-    private class Reaper implements IBinder.DeathRecipient {
-        int mPid;
-        int mHandle;
-        int mType;
-
-        Reaper(int handle, int pid, int type) {
-            mPid = pid;
-            mHandle = handle;
-            mType = type;
-        }
-
-        Reaper(int pid, int type) {
-            mPid = pid;
-            mType = type;
-        }
-
-        @Override
-        public void binderDied() {
-            synchronized (BluetoothService.this) {
-                if (DBG) Log.d(TAG, "Tracked app " + mPid + " died" + "Type:" + mType);
-                if (mType == RFCOMM_RECORD_REAPER) {
-                    checkAndRemoveRecord(mHandle, mPid);
-                } else if (mType == STATE_CHANGE_REAPER) {
-                    mStateChangeTracker.remove(mPid);
-                }
-            }
-        }
-    }
-
-
-    @Override
-    public boolean changeApplicationBluetoothState(boolean on,
-            IBluetoothStateChangeCallback callback, IBinder binder) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-
-        int pid = Binder.getCallingPid();
-        //mStateChangeTracker is a synchronized map
-        if (!mStateChangeTracker.containsKey(pid)) {
-            if (on) {
-                mStateChangeTracker.put(pid, callback);
-            } else {
-                return false;
-            }
-        } else if (!on) {
-            mStateChangeTracker.remove(pid);
-        }
-
-        if (binder != null) {
-            try {
-                binder.linkToDeath(new Reaper(pid, STATE_CHANGE_REAPER), 0);
-            } catch (RemoteException e) {
-                Log.e(TAG, "", e);
-                return false;
-            }
-        }
-
-        int type;
-        if (on) {
-            type = BluetoothAdapterStateMachine.PER_PROCESS_TURN_ON;
-        } else {
-            type = BluetoothAdapterStateMachine.PER_PROCESS_TURN_OFF;
-        }
-
-        mBluetoothState.sendMessage(type, callback);
-        return true;
-    }
-
-    boolean isApplicationStateChangeTrackerEmpty() {
-        return mStateChangeTracker.isEmpty();
-    }
-
-    void clearApplicationStateChangeTracker() {
-        mStateChangeTracker.clear();
-    }
-
-    Collection<IBluetoothStateChangeCallback> getApplicationStateChangeCallbacks() {
-        return mStateChangeTracker.values();
-    }
-
-    int getNumberOfApplicationStateChangeTrackers() {
-        return mStateChangeTracker.size();
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent == null) return;
-
-            String action = intent.getAction();
-            if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
-                ContentResolver resolver = context.getContentResolver();
-                // Query the airplane mode from Settings.System just to make sure that
-                // some random app is not sending this intent and disabling bluetooth
-                if (isAirplaneModeOn()) {
-                    mBluetoothState.sendMessage(BluetoothAdapterStateMachine.AIRPLANE_MODE_ON);
-                } else {
-                    mBluetoothState.sendMessage(BluetoothAdapterStateMachine.AIRPLANE_MODE_OFF);
-                }
-            } else if (Intent.ACTION_DOCK_EVENT.equals(action)) {
-                int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
-                if (DBG) Log.v(TAG, "Received ACTION_DOCK_EVENT with State:" + state);
-                if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                    mDockAddress = null;
-                    mDockPin = null;
-                } else {
-                    SharedPreferences.Editor editor =
-                        mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
-                                mContext.MODE_PRIVATE).edit();
-                    editor.putBoolean(SHARED_PREFERENCE_DOCK_ADDRESS + mDockAddress, true);
-                    editor.apply();
-                }
-            }
-        }
-    };
-
-    private void registerForAirplaneMode(IntentFilter filter) {
-        final ContentResolver resolver = mContext.getContentResolver();
-        final String airplaneModeRadios = Settings.System.getString(resolver,
-                Settings.System.AIRPLANE_MODE_RADIOS);
-        final String toggleableRadios = Settings.System.getString(resolver,
-                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
-
-        mIsAirplaneSensitive = airplaneModeRadios == null ? true :
-                airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
-        mIsAirplaneToggleable = toggleableRadios == null ? false :
-                toggleableRadios.contains(Settings.System.RADIO_BLUETOOTH);
-
-        if (mIsAirplaneSensitive) {
-            filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        }
-    }
-
-    /* Returns true if airplane mode is currently on */
-    /*package*/ final boolean isAirplaneModeOn() {
-        return Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
-    }
-
-    /* Broadcast the Uuid intent */
-    /*package*/ synchronized void sendUuidIntent(String address) {
-        ParcelUuid[] uuid = getUuidFromCache(address);
-        Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-        mUuidIntentTracker.remove(address);
-    }
-
-    /*package*/ synchronized void makeServiceChannelCallbacks(String address) {
-        for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
-                iter.hasNext();) {
-            RemoteService service = iter.next();
-            if (service.address.equals(address)) {
-                if (DBG) Log.d(TAG, "Cleaning up failed UUID channel lookup: "
-                    + service.address + " " + service.uuid);
-                IBluetoothCallback callback = mUuidCallbackTracker.get(service);
-                if (callback != null) {
-                    try {
-                        callback.onRfcommChannelFound(-1);
-                    } catch (RemoteException e) {Log.e(TAG, "", e);}
-                }
-
-                iter.remove();
-            }
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
-        if (getBluetoothStateInternal() != BluetoothAdapter.STATE_ON) {
-            return;
-        }
-
-        pw.println("mIsAirplaneSensitive = " + mIsAirplaneSensitive);
-        pw.println("mIsAirplaneToggleable = " + mIsAirplaneToggleable);
-
-        pw.println("Local address = " + getAddress());
-        pw.println("Local name = " + getName());
-        pw.println("isDiscovering() = " + isDiscovering());
-
-        mAdapter.getProfileProxy(mContext,
-                                 mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
-        mAdapter.getProfileProxy(mContext,
-                mBluetoothProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
-        mAdapter.getProfileProxy(mContext,
-                mBluetoothProfileServiceListener, BluetoothProfile.PAN);
-
-        dumpKnownDevices(pw);
-        dumpAclConnectedDevices(pw);
-        dumpHeadsetService(pw);
-        dumpInputDeviceProfile(pw);
-        dumpPanProfile(pw);
-        dumpApplicationServiceRecords(pw);
-        dumpProfileState(pw);
-    }
-
-    private void dumpProfileState(PrintWriter pw) {
-        pw.println("\n--Profile State dump--");
-        pw.println("\n Headset profile state:" +
-                mAdapter.getProfileConnectionState(BluetoothProfile.HEADSET));
-        pw.println("\n A2dp profile state:" +
-                mAdapter.getProfileConnectionState(BluetoothProfile.A2DP));
-        pw.println("\n HID profile state:" +
-                mAdapter.getProfileConnectionState(BluetoothProfile.INPUT_DEVICE));
-        pw.println("\n PAN profile state:" +
-                mAdapter.getProfileConnectionState(BluetoothProfile.PAN));
-    }
-
-    private void dumpHeadsetService(PrintWriter pw) {
-        pw.println("\n--Headset Service--");
-        if (mHeadsetProxy != null) {
-            List<BluetoothDevice> deviceList = mHeadsetProxy.getConnectedDevices();
-            if (deviceList.size() == 0) {
-                pw.println("No headsets connected");
-            } else {
-                BluetoothDevice device = deviceList.get(0);
-                pw.println("\ngetConnectedDevices[0] = " + device);
-                dumpHeadsetConnectionState(pw, device);
-                pw.println("getBatteryUsageHint() = " +
-                             mHeadsetProxy.getBatteryUsageHint(device));
-            }
-
-            deviceList.clear();
-            deviceList = mHeadsetProxy.getDevicesMatchingConnectionStates(new int[] {
-                     BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
-            pw.println("--Connected and Disconnected Headsets");
-            for (BluetoothDevice device: deviceList) {
-                pw.println(device);
-                if (mHeadsetProxy.isAudioConnected(device)) {
-                    pw.println("SCO audio connected to device:" + device);
-                }
-            }
-        }
-    }
-
-    private void dumpInputDeviceProfile(PrintWriter pw) {
-        pw.println("\n--Bluetooth Service- Input Device Profile");
-        if (mInputDevice != null) {
-            List<BluetoothDevice> deviceList = mInputDevice.getConnectedDevices();
-            if (deviceList.size() == 0) {
-                pw.println("No input devices connected");
-            } else {
-                pw.println("Number of connected devices:" + deviceList.size());
-                BluetoothDevice device = deviceList.get(0);
-                pw.println("getConnectedDevices[0] = " + device);
-                pw.println("Priority of Connected device = " + mInputDevice.getPriority(device));
-
-                switch (mInputDevice.getConnectionState(device)) {
-                    case BluetoothInputDevice.STATE_CONNECTING:
-                        pw.println("getConnectionState() = STATE_CONNECTING");
-                        break;
-                    case BluetoothInputDevice.STATE_CONNECTED:
-                        pw.println("getConnectionState() = STATE_CONNECTED");
-                        break;
-                    case BluetoothInputDevice.STATE_DISCONNECTING:
-                        pw.println("getConnectionState() = STATE_DISCONNECTING");
-                        break;
-                }
-            }
-            deviceList.clear();
-            deviceList = mInputDevice.getDevicesMatchingConnectionStates(new int[] {
-                     BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
-            pw.println("--Connected and Disconnected input devices");
-            for (BluetoothDevice device: deviceList) {
-                pw.println(device);
-            }
-        }
-    }
-
-    private void dumpPanProfile(PrintWriter pw) {
-        pw.println("\n--Bluetooth Service- Pan Profile");
-        if (mPan != null) {
-            List<BluetoothDevice> deviceList = mPan.getConnectedDevices();
-            if (deviceList.size() == 0) {
-                pw.println("No Pan devices connected");
-            } else {
-                pw.println("Number of connected devices:" + deviceList.size());
-                BluetoothDevice device = deviceList.get(0);
-                pw.println("getConnectedDevices[0] = " + device);
-
-                switch (mPan.getConnectionState(device)) {
-                    case BluetoothInputDevice.STATE_CONNECTING:
-                        pw.println("getConnectionState() = STATE_CONNECTING");
-                        break;
-                    case BluetoothInputDevice.STATE_CONNECTED:
-                        pw.println("getConnectionState() = STATE_CONNECTED");
-                        break;
-                    case BluetoothInputDevice.STATE_DISCONNECTING:
-                        pw.println("getConnectionState() = STATE_DISCONNECTING");
-                        break;
-                }
-            }
-            deviceList.clear();
-            deviceList = mPan.getDevicesMatchingConnectionStates(new int[] {
-                     BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
-            pw.println("--Connected and Disconnected Pan devices");
-            for (BluetoothDevice device: deviceList) {
-                pw.println(device);
-            }
-        }
-    }
-
-    private void dumpHeadsetConnectionState(PrintWriter pw,
-            BluetoothDevice device) {
-        switch (mHeadsetProxy.getConnectionState(device)) {
-            case BluetoothHeadset.STATE_CONNECTING:
-                pw.println("getConnectionState() = STATE_CONNECTING");
-                break;
-            case BluetoothHeadset.STATE_CONNECTED:
-                pw.println("getConnectionState() = STATE_CONNECTED");
-                break;
-            case BluetoothHeadset.STATE_DISCONNECTING:
-                pw.println("getConnectionState() = STATE_DISCONNECTING");
-                break;
-            case BluetoothHeadset.STATE_AUDIO_CONNECTED:
-                pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
-                break;
-        }
-    }
-
-    private void dumpApplicationServiceRecords(PrintWriter pw) {
-        pw.println("\n--Application Service Records--");
-        for (Integer handle : mServiceRecordToPid.keySet()) {
-            Integer pid = mServiceRecordToPid.get(handle).pid;
-            pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
-        }
-    }
-
-    private void dumpAclConnectedDevices(PrintWriter pw) {
-        String[] devicesObjectPath = getKnownDevices();
-        pw.println("\n--ACL connected devices--");
-        if (devicesObjectPath != null) {
-            for (String device : devicesObjectPath) {
-                pw.println(getAddressFromObjectPath(device));
-            }
-        }
-    }
-
-    private void dumpKnownDevices(PrintWriter pw) {
-        pw.println("\n--Known devices--");
-        for (String address : mDeviceProperties.keySet()) {
-            int bondState = mBondState.getBondState(address);
-            pw.printf("%s %10s (%d) %s\n", address,
-                       toBondStateString(bondState),
-                       mBondState.getAttempt(address),
-                       getRemoteName(address));
-
-            Map<ParcelUuid, Integer> uuidChannels = mDeviceServiceChannelCache.get(address);
-            if (uuidChannels == null) {
-                pw.println("\tuuids = null");
-            } else {
-                for (ParcelUuid uuid : uuidChannels.keySet()) {
-                    Integer channel = uuidChannels.get(uuid);
-                    if (channel == null) {
-                        pw.println("\t" + uuid);
-                    } else {
-                        pw.println("\t" + uuid + " RFCOMM channel = " + channel);
-                    }
-                }
-            }
-            for (RemoteService service : mUuidCallbackTracker.keySet()) {
-                if (service.address.equals(address)) {
-                    pw.println("\tPENDING CALLBACK: " + service.uuid);
-                }
-            }
-        }
-    }
-
-    private void getProfileProxy() {
-        mAdapter.getProfileProxy(mContext,
-                                 mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
-    }
-
-    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
-        new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET) {
-                mHeadsetProxy = (BluetoothHeadset) proxy;
-            } else if (profile == BluetoothProfile.INPUT_DEVICE) {
-                mInputDevice = (BluetoothInputDevice) proxy;
-            } else if (profile == BluetoothProfile.PAN) {
-                mPan = (BluetoothPan) proxy;
-            }
-        }
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET) {
-                mHeadsetProxy = null;
-            } else if (profile == BluetoothProfile.INPUT_DEVICE) {
-                mInputDevice = null;
-            } else if (profile == BluetoothProfile.PAN) {
-                mPan = null;
-            }
-        }
-    };
-
-    /* package */ static int bluezStringToScanMode(boolean pairable, boolean discoverable) {
-        if (pairable && discoverable)
-            return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
-        else if (pairable && !discoverable)
-            return BluetoothAdapter.SCAN_MODE_CONNECTABLE;
-        else
-            return BluetoothAdapter.SCAN_MODE_NONE;
-    }
-
-    /* package */ static String scanModeToBluezString(int mode) {
-        switch (mode) {
-        case BluetoothAdapter.SCAN_MODE_NONE:
-            return "off";
-        case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
-            return "connectable";
-        case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
-            return "discoverable";
-        }
-        return null;
-    }
-
-    /*package*/ String getAddressFromObjectPath(String objectPath) {
-        String adapterObjectPath = mAdapterProperties.getObjectPath();
-        if (adapterObjectPath == null || objectPath == null) {
-            Log.e(TAG, "getAddressFromObjectPath: AdapterObjectPath:" + adapterObjectPath +
-                    "  or deviceObjectPath:" + objectPath + " is null");
-            return null;
-        }
-        if (!objectPath.startsWith(adapterObjectPath)) {
-            Log.e(TAG, "getAddressFromObjectPath: AdapterObjectPath:" + adapterObjectPath +
-                    "  is not a prefix of deviceObjectPath:" + objectPath +
-                    "bluetoothd crashed ?");
-            return null;
-        }
-        String address = objectPath.substring(adapterObjectPath.length());
-        if (address != null) return address.replace('_', ':');
-
-        Log.e(TAG, "getAddressFromObjectPath: Address being returned is null");
-        return null;
-    }
-
-    /*package*/ String getObjectPathFromAddress(String address) {
-        String path = mAdapterProperties.getObjectPath();
-        if (path == null) {
-            Log.e(TAG, "Error: Object Path is null");
-            return null;
-        }
-        path = path + address.replace(":", "_");
-        return path;
-    }
-
-    /*package */ void setLinkTimeout(String address, int num_slots) {
-        String path = getObjectPathFromAddress(address);
-        boolean result = setLinkTimeoutNative(path, num_slots);
-
-        if (!result) Log.d(TAG, "Set Link Timeout to " + num_slots + " slots failed");
-    }
-
-    /**** Handlers for PAN  Profile ****/
-    // TODO: This needs to be converted to a state machine.
-
-    public boolean isTetheringOn() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.isTetheringOn();
-        }
-    }
-
-    /*package*/boolean allowIncomingTethering() {
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.allowIncomingTethering();
-        }
-    }
-
-    public void setBluetoothTethering(boolean value) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            mBluetoothPanProfileHandler.setBluetoothTethering(value);
-        }
-    }
-
-    public int getPanDeviceConnectionState(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.getPanDeviceConnectionState(device);
-        }
-    }
-
-    public boolean connectPanDevice(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-            "Need BLUETOOTH_ADMIN permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.connectPanDevice(device);
-        }
-    }
-
-    public List<BluetoothDevice> getConnectedPanDevices() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.getConnectedPanDevices();
-        }
-    }
-
-    public List<BluetoothDevice> getPanDevicesMatchingConnectionStates(
-            int[] states) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.getPanDevicesMatchingConnectionStates(states);
-        }
-    }
-
-    public boolean disconnectPanDevice(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-            "Need BLUETOOTH_ADMIN permission");
-        synchronized (mBluetoothPanProfileHandler) {
-            return mBluetoothPanProfileHandler.disconnectPanDevice(device);
-        }
-    }
-
-    /*package*/void handlePanDeviceStateChange(BluetoothDevice device,
-                                                             String iface,
-                                                             int state,
-                                                             int role) {
-        synchronized (mBluetoothPanProfileHandler) {
-            mBluetoothPanProfileHandler.handlePanDeviceStateChange(device, iface, state, role);
-        }
-    }
-
-    /*package*/void handlePanDeviceStateChange(BluetoothDevice device,
-                                                             int state, int role) {
-        synchronized (mBluetoothPanProfileHandler) {
-            mBluetoothPanProfileHandler.handlePanDeviceStateChange(device, null, state, role);
-        }
-    }
-
-    /**** Handlers for Input Device Profile ****/
-    // This needs to be converted to state machine
-
-    public boolean connectInputDevice(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(device.getAddress());
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.connectInputDevice(device, state);
-        }
-    }
-
-    public boolean connectInputDeviceInternal(BluetoothDevice device) {
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.connectInputDeviceInternal(device);
-        }
-    }
-
-    public boolean disconnectInputDevice(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(device.getAddress());
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.disconnectInputDevice(device, state);
-        }
-    }
-
-    public boolean disconnectInputDeviceInternal(BluetoothDevice device) {
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.disconnectInputDeviceInternal(device);
-        }
-    }
-
-    public int getInputDeviceConnectionState(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.getInputDeviceConnectionState(device);
-        }
-    }
-
-    public List<BluetoothDevice> getConnectedInputDevices() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.getConnectedInputDevices();
-        }
-    }
-
-    public List<BluetoothDevice> getInputDevicesMatchingConnectionStates(
-            int[] states) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.getInputDevicesMatchingConnectionStates(states);
-        }
-    }
-
-
-    public int getInputDevicePriority(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.getInputDevicePriority(device);
-        }
-    }
-
-    public boolean setInputDevicePriority(BluetoothDevice device, int priority) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.setInputDevicePriority(device, priority);
-        }
-    }
-
-    /**
-     * Handle incoming profile acceptance for profiles handled by Bluetooth Service,
-     * currently PAN and HID. This also is the catch all for all rejections for profiles
-     * that is not supported.
-     *
-     * @param device - Bluetooth Device
-     * @param allow - true / false
-     * @return
-     */
-    public boolean allowIncomingProfileConnect(BluetoothDevice device, boolean allow) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                                "Need BLUETOOTH_ADMIN permission");
-        String address = device.getAddress();
-        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-            return false;
-        }
-
-        Integer data = getAuthorizationAgentRequestData(address);
-        if (data == null) {
-            Log.w(TAG, "allowIncomingProfileConnect(" + device +
-                  ") called but no native data available");
-            return false;
-        }
-        if (DBG) log("allowIncomingProfileConnect: " + device + " : " + allow + " : " + data);
-        return setAuthorizationNative(address, allow, data.intValue());
-    }
-
-    /*package*/List<BluetoothDevice> lookupInputDevicesMatchingStates(int[] states) {
-        synchronized (mBluetoothInputProfileHandler) {
-            return mBluetoothInputProfileHandler.lookupInputDevicesMatchingStates(states);
-        }
-    }
-
-    /*package*/void handleInputDevicePropertyChange(String address, boolean connected) {
-        synchronized (mBluetoothInputProfileHandler) {
-            mBluetoothInputProfileHandler.handleInputDevicePropertyChange(address, connected);
-        }
-    }
-
-    /**** Handlers for Health Device Profile ****/
-    // TODO: All these need to be converted to a state machine.
-
-    public boolean registerAppConfiguration(BluetoothHealthAppConfiguration config,
-                                            IBluetoothHealthCallback callback) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-                return mBluetoothHealthProfileHandler.registerAppConfiguration(config, callback);
-        }
-    }
-
-    public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-                return mBluetoothHealthProfileHandler.unregisterAppConfiguration(config);
-        }
-    }
-
-
-    public boolean connectChannelToSource(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.connectChannelToSource(device,
-                    config);
-        }
-    }
-
-    public boolean connectChannelToSink(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config, int channelType) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                                                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.connectChannel(device, config,
-                    channelType);
-        }
-    }
-
-    public boolean disconnectChannel(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config, int id) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.disconnectChannel(device, config, id);
-        }
-    }
-
-    public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device,
-            BluetoothHealthAppConfiguration config) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.getMainChannelFd(device, config);
-        }
-    }
-
-    /*package*/ void onHealthDevicePropertyChanged(String devicePath,
-            String channelPath) {
-        synchronized (mBluetoothHealthProfileHandler) {
-            mBluetoothHealthProfileHandler.onHealthDevicePropertyChanged(devicePath,
-                    channelPath);
-        }
-    }
-
-    /*package*/ void onHealthDeviceChannelChanged(String devicePath,
-            String channelPath, boolean exists) {
-        synchronized(mBluetoothHealthProfileHandler) {
-            mBluetoothHealthProfileHandler.onHealthDeviceChannelChanged(devicePath,
-                    channelPath, exists);
-        }
-    }
-
-    /*package*/ void onHealthDeviceChannelConnectionError(int channelCode,
-            int newState) {
-        synchronized(mBluetoothHealthProfileHandler) {
-            mBluetoothHealthProfileHandler.onHealthDeviceChannelConnectionError(channelCode,
-                                                                                newState);
-        }
-    }
-
-    public int getHealthDeviceConnectionState(BluetoothDevice device) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.getHealthDeviceConnectionState(device);
-        }
-    }
-
-    public List<BluetoothDevice> getConnectedHealthDevices() {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.getConnectedHealthDevices();
-        }
-    }
-
-    public List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(
-            int[] states) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
-        synchronized (mBluetoothHealthProfileHandler) {
-            return mBluetoothHealthProfileHandler.
-                    getHealthDevicesMatchingConnectionStates(states);
-        }
-    }
-
-    /*package*/boolean notifyIncomingHidConnection(String address) {
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state == null) {
-            return false;
-        }
-        Message msg = new Message();
-        msg.what = BluetoothDeviceProfileState.CONNECT_HID_INCOMING;
-        state.sendMessage(msg);
-        return true;
-    }
-
-    public boolean connectHeadset(String address) {
-        if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
-
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.CONNECT_HFP_OUTGOING;
-            msg.obj = state;
-            mHfpProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    public boolean disconnectHeadset(String address) {
-        if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
-
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.DISCONNECT_HFP_OUTGOING;
-            msg.obj = state;
-            mHfpProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    public boolean connectSink(String address) {
-        if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
-
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.CONNECT_A2DP_OUTGOING;
-            msg.obj = state;
-            mA2dpProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    public boolean disconnectSink(String address) {
-        if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
-
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            Message msg = new Message();
-            msg.arg1 = BluetoothDeviceProfileState.DISCONNECT_A2DP_OUTGOING;
-            msg.obj = state;
-            mA2dpProfileState.sendMessage(msg);
-            return true;
-        }
-        return false;
-    }
-
-    BluetoothDeviceProfileState addProfileState(String address, boolean setTrust) {
-        BluetoothDeviceProfileState state =
-            new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust);
-        mDeviceProfileState.put(address, state);
-        state.start();
-        return state;
-    }
-
-    void removeProfileState(String address) {
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state == null) return;
-
-        state.doQuit();
-        mDeviceProfileState.remove(address);
-    }
-
-    String[] getKnownDevices() {
-        String[] bonds = null;
-        String val = getProperty("Devices", true);
-        if (val != null) {
-            bonds = val.split(",");
-        }
-        return bonds;
-    }
-
-    private void initProfileState() {
-        String[] bonds = null;
-        String val = getProperty("Devices", false);
-        if (val != null) {
-            bonds = val.split(",");
-        }
-        if (bonds == null) {
-            return;
-        }
-        for (String path : bonds) {
-            String address = getAddressFromObjectPath(path);
-            BluetoothDeviceProfileState state = addProfileState(address, false);
-        }
-    }
-
-    private void autoConnect() {
-        synchronized (this) {
-            if (!mAllowConnect) {
-                Log.d(TAG, "Not auto-connecting devices because of temporary BT on state.");
-                return;
-            }
-        }
-
-        String[] bonds = getKnownDevices();
-        if (bonds == null) {
-            return;
-        }
-        for (String path : bonds) {
-            String address = getAddressFromObjectPath(path);
-            BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-            if (state != null) {
-                Message msg = new Message();
-                msg.what = BluetoothDeviceProfileState.AUTO_CONNECT_PROFILES;
-                state.sendMessage(msg);
-            }
-        }
-    }
-
-    public boolean notifyIncomingConnection(String address, boolean rejected) {
-        synchronized (this) {
-            if (!mAllowConnect) {
-                Log.d(TAG, "Not allowing incoming connection because of temporary BT on state.");
-                return false;
-            }
-        }
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) {
-            Message msg = new Message();
-            if (rejected) {
-                if (mA2dpService.getPriority(getRemoteDevice(address)) >=
-                    BluetoothProfile.PRIORITY_ON) {
-                    msg.what = BluetoothDeviceProfileState.CONNECT_OTHER_PROFILES;
-                    msg.arg1 = BluetoothDeviceProfileState.CONNECT_A2DP_OUTGOING;
-                    state.sendMessageDelayed(msg,
-                        BluetoothDeviceProfileState.CONNECT_OTHER_PROFILES_DELAY);
-                }
-            } else {
-                msg.what = BluetoothDeviceProfileState.CONNECT_HFP_INCOMING;
-                state.sendMessage(msg);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /*package*/ boolean notifyIncomingA2dpConnection(String address, boolean rejected) {
-        synchronized (this) {
-            if (!mAllowConnect) {
-                Log.d(TAG, "Not allowing a2dp connection because of temporary BT on state.");
-                return false;
-            }
-        }
-
-       BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-       if (state != null) {
-           Message msg = new Message();
-           if (rejected) {
-               if (mHeadsetProxy.getPriority(getRemoteDevice(address)) >=
-                   BluetoothProfile.PRIORITY_ON) {
-                   msg.what = BluetoothDeviceProfileState.CONNECT_OTHER_PROFILES;
-                   msg.arg1 = BluetoothDeviceProfileState.CONNECT_HFP_OUTGOING;
-                   state.sendMessageDelayed(msg,
-                             BluetoothDeviceProfileState.CONNECT_OTHER_PROFILES_DELAY);
-               }
-           } else {
-               msg.what = BluetoothDeviceProfileState.CONNECT_A2DP_INCOMING;
-               state.sendMessage(msg);
-           }
-           return true;
-       }
-       return false;
-    }
-
-    /*package*/ void setA2dpService(BluetoothA2dpService a2dpService) {
-        mA2dpService = a2dpService;
-    }
-
-    /*package*/ Integer getAuthorizationAgentRequestData(String address) {
-        Integer data = mEventLoop.getAuthorizationAgentRequestData().remove(address);
-        return data;
-    }
-
-    public void sendProfileStateMessage(int profile, int cmd) {
-        Message msg = new Message();
-        msg.what = cmd;
-        if (profile == BluetoothProfileState.HFP) {
-            mHfpProfileState.sendMessage(msg);
-        } else if (profile == BluetoothProfileState.A2DP) {
-            mA2dpProfileState.sendMessage(msg);
-        }
-    }
-
-    public int getAdapterConnectionState() {
-        return mAdapterConnectionState;
-    }
-
-    public int getProfileConnectionState(int profile) {
-        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-
-        Pair<Integer, Integer> state = mProfileConnectionState.get(profile);
-        if (state == null) return BluetoothProfile.STATE_DISCONNECTED;
-
-        return state.first;
-    }
-
-    private void updateProfileConnectionState(int profile, int newState, int oldState) {
-        // mProfileConnectionState is a hashmap -
-        // <Integer, Pair<Integer, Integer>>
-        // The key is the profile, the value is a pair. first element
-        // is the state and the second element is the number of devices
-        // in that state.
-        int numDev = 1;
-        int newHashState = newState;
-        boolean update = true;
-
-        // The following conditions are considered in this function:
-        // 1. If there is no record of profile and state - update
-        // 2. If a new device's state is current hash state - increment
-        //    number of devices in the state.
-        // 3. If a state change has happened to Connected or Connecting
-        //    (if current state is not connected), update.
-        // 4. If numDevices is 1 and that device state is being updated, update
-        // 5. If numDevices is > 1 and one of the devices is changing state,
-        //    decrement numDevices but maintain oldState if it is Connected or
-        //    Connecting
-        Pair<Integer, Integer> stateNumDev = mProfileConnectionState.get(profile);
-        if (stateNumDev != null) {
-            int currHashState = stateNumDev.first;
-            numDev = stateNumDev.second;
-
-            if (newState == currHashState) {
-                numDev ++;
-            } else if (newState == BluetoothProfile.STATE_CONNECTED ||
-                   (newState == BluetoothProfile.STATE_CONNECTING &&
-                    currHashState != BluetoothProfile.STATE_CONNECTED)) {
-                 numDev = 1;
-            } else if (numDev == 1 && oldState == currHashState) {
-                 update = true;
-            } else if (numDev > 1 && oldState == currHashState) {
-                 numDev --;
-
-                 if (currHashState == BluetoothProfile.STATE_CONNECTED ||
-                     currHashState == BluetoothProfile.STATE_CONNECTING) {
-                    newHashState = currHashState;
-                 }
-            } else {
-                 update = false;
-            }
-        }
-
-        if (update) {
-            mProfileConnectionState.put(profile, new Pair<Integer, Integer>(newHashState,
-                    numDev));
-        }
-    }
-
-    public synchronized void sendConnectionStateChange(BluetoothDevice
-            device, int profile, int state, int prevState) {
-        // Since this is a binder call check if Bluetooth is on still
-        if (getBluetoothStateInternal() == BluetoothAdapter.STATE_OFF) return;
-
-        if (!validateProfileConnectionState(state) ||
-                !validateProfileConnectionState(prevState)) {
-            // Previously, an invalid state was broadcast anyway,
-            // with the invalid state converted to -1 in the intent.
-            // Better to log an error and not send an intent with
-            // invalid contents or set mAdapterConnectionState to -1.
-            Log.e(TAG, "Error in sendConnectionStateChange: "
-                    + "prevState " + prevState + " state " + state);
-            return;
-        }
-
-        updateProfileConnectionState(profile, state, prevState);
-
-        if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
-            mAdapterConnectionState = state;
-
-            if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                mBluetoothState.sendMessage(BluetoothAdapterStateMachine.ALL_DEVICES_DISCONNECTED);
-            }
-
-            Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
-                    convertToAdapterState(state));
-            intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE,
-                    convertToAdapterState(prevState));
-            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-            Log.d(TAG, "CONNECTION_STATE_CHANGE: " + device + ": "
-                    + prevState + " -> " + state);
-        }
-    }
-
-    private boolean validateProfileConnectionState(int state) {
-        return (state == BluetoothProfile.STATE_DISCONNECTED ||
-                state == BluetoothProfile.STATE_CONNECTING ||
-                state == BluetoothProfile.STATE_CONNECTED ||
-                state == BluetoothProfile.STATE_DISCONNECTING);
-    }
-
-    private int convertToAdapterState(int state) {
-        switch (state) {
-            case BluetoothProfile.STATE_DISCONNECTED:
-                return BluetoothAdapter.STATE_DISCONNECTED;
-            case BluetoothProfile.STATE_DISCONNECTING:
-                return BluetoothAdapter.STATE_DISCONNECTING;
-            case BluetoothProfile.STATE_CONNECTED:
-                return BluetoothAdapter.STATE_CONNECTED;
-            case BluetoothProfile.STATE_CONNECTING:
-                return BluetoothAdapter.STATE_CONNECTING;
-        }
-        Log.e(TAG, "Error in convertToAdapterState");
-        return -1;
-    }
-
-    private boolean updateCountersAndCheckForConnectionStateChange(int state, int prevState) {
-        switch (prevState) {
-            case BluetoothProfile.STATE_CONNECTING:
-                mProfilesConnecting--;
-                break;
-
-            case BluetoothProfile.STATE_CONNECTED:
-                mProfilesConnected--;
-                break;
-
-            case BluetoothProfile.STATE_DISCONNECTING:
-                mProfilesDisconnecting--;
-                break;
-        }
-
-        switch (state) {
-            case BluetoothProfile.STATE_CONNECTING:
-                mProfilesConnecting++;
-                return (mProfilesConnected == 0 && mProfilesConnecting == 1);
-
-            case BluetoothProfile.STATE_CONNECTED:
-                mProfilesConnected++;
-                return (mProfilesConnected == 1);
-
-            case BluetoothProfile.STATE_DISCONNECTING:
-                mProfilesDisconnecting++;
-                return (mProfilesConnected == 0 && mProfilesDisconnecting == 1);
-
-            case BluetoothProfile.STATE_DISCONNECTED:
-                return (mProfilesConnected == 0 && mProfilesConnecting == 0);
-
-            default:
-                return true;
-        }
-    }
-
-    private void createIncomingConnectionStateFile() {
-        File f = new File(INCOMING_CONNECTION_FILE);
-        if (!f.exists()) {
-            try {
-                f.createNewFile();
-            } catch (IOException e) {
-                Log.e(TAG, "IOException: cannot create file");
-            }
-        }
-    }
-
-    /** @hide */
-    public Pair<Integer, String> getIncomingState(String address) {
-        if (mIncomingConnections.isEmpty()) {
-            createIncomingConnectionStateFile();
-            readIncomingConnectionState();
-        }
-        return mIncomingConnections.get(address);
-    }
-
-    private void readIncomingConnectionState() {
-        synchronized(mIncomingConnections) {
-            FileInputStream fstream = null;
-            try {
-              fstream = new FileInputStream(INCOMING_CONNECTION_FILE);
-              DataInputStream in = new DataInputStream(fstream);
-              BufferedReader file = new BufferedReader(new InputStreamReader(in));
-              String line;
-              while((line = file.readLine()) != null) {
-                  line = line.trim();
-                  if (line.length() == 0) continue;
-                  String[] value = line.split(",");
-                  if (value != null && value.length == 3) {
-                      Integer val1 = Integer.parseInt(value[1]);
-                      Pair<Integer, String> val = new Pair(val1, value[2]);
-                      mIncomingConnections.put(value[0], val);
-                  }
-              }
-            } catch (FileNotFoundException e) {
-                log("FileNotFoundException: readIncomingConnectionState" + e.toString());
-            } catch (IOException e) {
-                log("IOException: readIncomingConnectionState" + e.toString());
-            } finally {
-                if (fstream != null) {
-                    try {
-                        fstream.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
-    }
-
-    private void truncateIncomingConnectionFile() {
-        RandomAccessFile r = null;
-        try {
-            r = new RandomAccessFile(INCOMING_CONNECTION_FILE, "rw");
-            r.setLength(0);
-        } catch (FileNotFoundException e) {
-            log("FileNotFoundException: truncateIncomingConnectionState" + e.toString());
-        } catch (IOException e) {
-            log("IOException: truncateIncomingConnectionState" + e.toString());
-        } finally {
-            if (r != null) {
-                try {
-                    r.close();
-                } catch (IOException e) {
-                    // ignore
-                 }
-            }
-        }
-    }
-
-    /** @hide */
-    public void writeIncomingConnectionState(String address, Pair<Integer, String> data) {
-        synchronized(mIncomingConnections) {
-            mIncomingConnections.put(address, data);
-
-            truncateIncomingConnectionFile();
-            BufferedWriter out = null;
-            StringBuilder value = new StringBuilder();
-            try {
-                out = new BufferedWriter(new FileWriter(INCOMING_CONNECTION_FILE, true));
-                for (String devAddress: mIncomingConnections.keySet()) {
-                  Pair<Integer, String> val = mIncomingConnections.get(devAddress);
-                  value.append(devAddress);
-                  value.append(",");
-                  value.append(val.first.toString());
-                  value.append(",");
-                  value.append(val.second);
-                  value.append("\n");
-                }
-                out.write(value.toString());
-            } catch (FileNotFoundException e) {
-                log("FileNotFoundException: writeIncomingConnectionState" + e.toString());
-            } catch (IOException e) {
-                log("IOException: writeIncomingConnectionState" + e.toString());
-            } finally {
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
-            }
-        }
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-
-    private native static void classInitNative();
-    private native void initializeNativeDataNative();
-    private native boolean setupNativeDataNative();
-    private native boolean tearDownNativeDataNative();
-    private native void cleanupNativeDataNative();
-    /*package*/ native String getAdapterPathNative();
-
-    private native int isEnabledNative();
-    /*package*/ native int enableNative();
-    /*package*/ native int disableNative();
-
-    /*package*/ native Object[] getAdapterPropertiesNative();
-    private native Object[] getDevicePropertiesNative(String objectPath);
-    private native boolean setAdapterPropertyStringNative(String key, String value);
-    private native boolean setAdapterPropertyIntegerNative(String key, int value);
-    private native boolean setAdapterPropertyBooleanNative(String key, int value);
-
-    private native boolean startDiscoveryNative();
-    private native boolean stopDiscoveryNative();
-
-    private native boolean createPairedDeviceNative(String address, int timeout_ms);
-    private native boolean createPairedDeviceOutOfBandNative(String address, int timeout_ms);
-    private native byte[] readAdapterOutOfBandDataNative();
-
-    private native boolean cancelDeviceCreationNative(String address);
-    private native boolean removeDeviceNative(String objectPath);
-    private native int getDeviceServiceChannelNative(String objectPath, String uuid,
-            int attributeId);
-
-    private native boolean cancelPairingUserInputNative(String address, int nativeData);
-    private native boolean setPinNative(String address, String pin, int nativeData);
-    private native boolean setPasskeyNative(String address, int passkey, int nativeData);
-    private native boolean setPairingConfirmationNative(String address, boolean confirm,
-            int nativeData);
-    private native boolean setRemoteOutOfBandDataNative(String address, byte[] hash,
-                                                        byte[] randomizer, int nativeData);
-
-    private native boolean setDevicePropertyBooleanNative(String objectPath, String key,
-            int value);
-    private native boolean setDevicePropertyStringNative(String objectPath, String key,
-            String value);
-    private native boolean createDeviceNative(String address);
-    /*package*/ native boolean discoverServicesNative(String objectPath, String pattern);
-
-    private native int addRfcommServiceRecordNative(String name, long uuidMsb, long uuidLsb,
-            short channel);
-    private native boolean removeServiceRecordNative(int handle);
-    private native boolean setLinkTimeoutNative(String path, int num_slots);
-
-    native boolean connectInputDeviceNative(String path);
-    native boolean disconnectInputDeviceNative(String path);
-
-    native boolean setBluetoothTetheringNative(boolean value, String nap, String bridge);
-    native boolean connectPanDeviceNative(String path, String dstRole);
-    native boolean disconnectPanDeviceNative(String path);
-    native boolean disconnectPanServerDeviceNative(String path,
-            String address, String iface);
-
-    private native int[] addReservedServiceRecordsNative(int[] uuuids);
-    private native boolean removeReservedServiceRecordsNative(int[] handles);
-
-    // Health API
-    native String registerHealthApplicationNative(int dataType, String role, String name,
-            String channelType);
-    native String registerHealthApplicationNative(int dataType, String role, String name);
-    native boolean unregisterHealthApplicationNative(String path);
-    native boolean createChannelNative(String devicePath, String appPath, String channelType,
-                                       int code);
-    native boolean destroyChannelNative(String devicePath, String channelpath, int code);
-    native String getMainChannelNative(String path);
-    native String getChannelApplicationNative(String channelPath);
-    native ParcelFileDescriptor getChannelFdNative(String channelPath);
-    native boolean releaseChannelFdNative(String channelPath);
-    native boolean setAuthorizationNative(String address, boolean value, int data);
-}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index a968768..1105038 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -216,12 +216,6 @@
     
     /** Hide the surface. Equivalent to calling hide(). @hide */
     public static final int SURFACE_HIDDEN    = 0x01;
-    
-    /** Freeze the surface. Equivalent to calling freeze(). @hide */
-    public static final int SURFACE_FROZEN     = 0x02;
-
-    /** Enable dithering when compositing this surface @hide */
-    public static final int SURFACE_DITHER    = 0x04;
 
     // The mSurfaceControl will only be present for Surfaces used by the window
     // server or system processes. When this class is parceled we defer to the
@@ -413,22 +407,6 @@
     /*
      * set display parameters & screenshots
      */
-    
-    /**
-     * Freezes the specified display, No updating of the screen will occur
-     * until unfreezeDisplay() is called. Everything else works as usual though,
-     * in particular transactions.
-     * @param display
-     * @hide
-     */
-    public static native   void freezeDisplay(int display);
-
-    /**
-     * resume updating the specified display.
-     * @param display
-     * @hide
-     */
-    public static native   void unfreezeDisplay(int display);
 
     /**
      * set the orientation of the given display.
@@ -503,12 +481,6 @@
     /** @hide */
     public native   void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
     /** @hide */
-    public native   void freeze();
-    /** @hide */
-    public native   void unfreeze();
-    /** @hide */
-    public native   void setFreezeTint(int tint);
-    /** @hide */
     public native   void setFlags(int flags, int mask);
     /** @hide */
     public native   void setWindowCrop(Rect crop);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f1bcc65..0336b2f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -538,7 +538,9 @@
         public static final int FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800;
         
         /** Window flag: turn on dithering when compositing this window to
-         *  the screen. */
+         *  the screen.
+         * @deprecated This flag is no longer used. */
+        @Deprecated
         public static final int FLAG_DITHER             = 0x00001000;
         
         /** Window flag: don't allow screen shots while this window is
@@ -726,7 +728,6 @@
          * @see #FLAG_LAYOUT_NO_LIMITS
          * @see #FLAG_FULLSCREEN
          * @see #FLAG_FORCE_NOT_FULLSCREEN
-         * @see #FLAG_DITHER
          * @see #FLAG_SECURE
          * @see #FLAG_SCALED
          * @see #FLAG_IGNORE_CHEEK_PRESSES
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 2545cd81..7691f00 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -724,9 +724,9 @@
     }
 
     /**
-     * Restores the state of this WebView from the given map used in
-     * {@link android.app.Activity#onRestoreInstanceState}. This method should
-     * be called to restore the state of this WebView before using the object. If
+     * Restores the state of this WebView from the given Bundle. This method is
+     * intended for use in {@link android.app.Activity#onRestoreInstanceState}
+     * and should be called to restore the state of this WebView. If
      * it is called after this WebView has had a chance to build state (load
      * pages, create a back/forward list, etc.) there may be undesirable
      * side-effects. Please note that this method no longer restores the
@@ -1550,7 +1550,6 @@
     @Deprecated
     public void emulateShiftHeld() {
         checkThread();
-        mProvider.emulateShiftHeld();
     }
 
     /**
@@ -1656,7 +1655,6 @@
     @Deprecated
     public void debugDump() {
         checkThread();
-        mProvider.debugDump();
     }
 
     /**
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 8c30945..bef6db9 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -3550,7 +3550,8 @@
      * See {@link WebView#setFindListener(WebView.FindListener)}.
      * @hide
      */
-     public void setFindListener(WebView.FindListener listener) {
+     @Override
+    public void setFindListener(WebView.FindListener listener) {
          mFindListener = listener;
      }
 
@@ -3573,6 +3574,7 @@
         return findAllBody(find, false);
     }
 
+    @Override
     public void findAllAsync(String find) {
         findAllBody(find, true);
     }
@@ -3611,6 +3613,7 @@
      *             If false and text is non-null, perform a find all.
      * @return boolean True if the find dialog is shown, false otherwise.
      */
+    @Override
     public boolean showFindDialog(String text, boolean showIme) {
         FindActionModeCallback callback = new FindActionModeCallback(mContext);
         if (mWebView.getParent() == null || mWebView.startActionMode(callback) == null) {
@@ -5235,14 +5238,6 @@
     }
 
     /**
-     * See {@link WebView#emulateShiftHeld()}
-     */
-    @Override
-    @Deprecated
-    public void emulateShiftHeld() {
-    }
-
-    /**
      * Select all of the text in this WebView.
      *
      * This is an implementation detail.
@@ -6487,6 +6482,7 @@
     private DrawData mDelaySetPicture;
     private DrawData mLoadedPicture;
 
+    @Override
     public void setMapTrackballToArrowKeys(boolean setMap) {
         mMapTrackballToArrowKeys = setMap;
     }
@@ -6713,6 +6709,7 @@
         }
     }
 
+    @Override
     public void flingScroll(int vx, int vy) {
         mScroller.fling(getScrollX(), getScrollY(), vx, vy, 0, computeMaxScrollX(), 0,
                 computeMaxScrollY(), mOverflingDistance, mOverflingDistance);
@@ -8451,14 +8448,6 @@
     }
 
     /**
-     * See {@link WebView#debugDump()}
-     */
-    @Override
-    @Deprecated
-    public void debugDump() {
-    }
-
-    /**
      * Enable the communication b/t the webView and VideoViewProxy
      *
      * only used by the Browser
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index ad28b17..c9f9fbd 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -221,8 +221,6 @@
 
     public WebSettings getSettings();
 
-    public void emulateShiftHeld();
-
     public void setMapTrackballToArrowKeys(boolean setMap);
 
     public void flingScroll(int vx, int vy);
@@ -237,8 +235,6 @@
 
     public boolean zoomOut();
 
-    public void debugDump();
-
     public void dumpViewHierarchyWithProperties(BufferedWriter out, int level);
 
     public View findHierarchyView(String className, int hashCode);
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 4eb169b..2037c3a 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -497,7 +497,7 @@
         // Default activity button.
         final int activityCount = mAdapter.getActivityCount();
         final int historySize = mAdapter.getHistorySize();
-        if (activityCount > 0 && historySize > 0) {
+        if (activityCount==1 || activityCount > 1 && historySize > 0) {
             mDefaultActivityButton.setVisibility(VISIBLE);
             ResolveInfo activity = mAdapter.getDefaultActivity();
             PackageManager packageManager = mContext.getPackageManager();
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index f41fcc6..650681a 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -111,16 +111,22 @@
     
     public void onBeginPackageChanges() {
     }
-    
+
+    /**
+     * Called when a package is really added (and not replaced).
+     */
     public void onPackageAdded(String packageName, int uid) {
     }
-    
+
+    /**
+     * Called when a package is really removed (and not replaced).
+     */
     public void onPackageRemoved(String packageName, int uid) {
     }
-    
+
     public void onPackageUpdateStarted(String packageName, int uid) {
     }
-    
+
     public void onPackageUpdateFinished(String packageName, int uid) {
     }
     
@@ -144,10 +150,16 @@
     public static final int PACKAGE_UPDATING = 1;
     public static final int PACKAGE_TEMPORARY_CHANGE = 2;
     public static final int PACKAGE_PERMANENT_CHANGE = 3;
-    
+
+    /**
+     * Called when a package disappears for any reason.
+     */
     public void onPackageDisappeared(String packageName, int reason) {
     }
-    
+
+    /**
+     * Called when a package appears for any reason.
+     */
     public void onPackageAppeared(String packageName, int reason) {
     }
     
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index f54575b..511417e 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -489,8 +489,10 @@
 
     @Override
     protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        if (p instanceof LayoutParams) {
-            LayoutParams result = new LayoutParams((LayoutParams) p);
+        if (p != null) {
+            final LayoutParams result = p instanceof LayoutParams
+                    ? new LayoutParams((LayoutParams) p)
+                    : new LayoutParams(p);
             if (result.gravity <= Gravity.NO_GRAVITY) {
                 result.gravity = Gravity.CENTER_VERTICAL;
             }
@@ -563,6 +565,10 @@
             super(c, attrs);
         }
 
+        public LayoutParams(ViewGroup.LayoutParams other) {
+            super(other);
+        }
+
         public LayoutParams(LayoutParams other) {
             super((LinearLayout.LayoutParams) other);
             isOverflowButton = other.isOverflowButton;
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index eb39b12..e429ffc 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -138,14 +138,6 @@
 	android_util_FileObserver.cpp \
 	android/opengl/poly_clip.cpp.arm \
 	android/opengl/util.cpp.arm \
-	android_bluetooth_HeadsetBase.cpp \
-	android_bluetooth_common.cpp \
-	android_bluetooth_BluetoothAudioGateway.cpp \
-	android_bluetooth_BluetoothSocket.cpp \
-	android_bluetooth_c.c \
-	android_server_BluetoothService.cpp \
-	android_server_BluetoothEventLoop.cpp \
-	android_server_BluetoothA2dpService.cpp \
 	android_server_NetworkManagementSocketTagger.cpp \
 	android_server_Watchdog.cpp \
 	android_ddm_DdmHandleNativeHeap.cpp \
@@ -236,7 +228,6 @@
 	external/dbus \
 	system/bluetooth/bluez-clean-headers
 LOCAL_CFLAGS += -DHAVE_BLUETOOTH
-LOCAL_SHARED_LIBRARIES += libbluedroid libdbus
 endif
 
 LOCAL_SHARED_LIBRARIES += \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 532a6e5..f0dd321 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -150,12 +150,6 @@
 extern int register_android_text_AndroidCharacter(JNIEnv *env);
 extern int register_android_text_AndroidBidi(JNIEnv *env);
 extern int register_android_opengl_classes(JNIEnv *env);
-extern int register_android_bluetooth_HeadsetBase(JNIEnv* env);
-extern int register_android_bluetooth_BluetoothAudioGateway(JNIEnv* env);
-extern int register_android_bluetooth_BluetoothSocket(JNIEnv *env);
-extern int register_android_server_BluetoothService(JNIEnv* env);
-extern int register_android_server_BluetoothEventLoop(JNIEnv *env);
-extern int register_android_server_BluetoothA2dpService(JNIEnv* env);
 extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
 extern int register_android_server_Watchdog(JNIEnv* env);
 extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
@@ -1172,12 +1166,6 @@
     REG_JNI(register_android_media_ToneGenerator),
 
     REG_JNI(register_android_opengl_classes),
-    REG_JNI(register_android_bluetooth_HeadsetBase),
-    REG_JNI(register_android_bluetooth_BluetoothAudioGateway),
-    REG_JNI(register_android_bluetooth_BluetoothSocket),
-    REG_JNI(register_android_server_BluetoothService),
-    REG_JNI(register_android_server_BluetoothEventLoop),
-    REG_JNI(register_android_server_BluetoothA2dpService),
     REG_JNI(register_android_server_NetworkManagementSocketTagger),
     REG_JNI(register_android_server_Watchdog),
     REG_JNI(register_android_ddm_DdmHandleNativeHeap),
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
deleted file mode 100644
index 294c626..0000000
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothAudioGateway.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_bluetooth_c.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#define USE_ACCEPT_DIRECTLY (0)
-#define USE_SELECT (0) /* 1 for select(), 0 for poll(); used only when
-                          USE_ACCEPT_DIRECTLY == 0 */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/uio.h>
-#include <ctype.h>
-
-#if USE_SELECT
-#include <sys/select.h>
-#else
-#include <sys/poll.h>
-#endif
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sco.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
-    /* in */
-static jfieldID field_mHandsfreeAgRfcommChannel;
-static jfieldID field_mHeadsetAgRfcommChannel;
-    /* out */
-static jfieldID field_mTimeoutRemainingMs; /* out */
-
-static jfieldID field_mConnectingHeadsetAddress;
-static jfieldID field_mConnectingHeadsetRfcommChannel; /* -1 when not connected */
-static jfieldID field_mConnectingHeadsetSocketFd;
-
-static jfieldID field_mConnectingHandsfreeAddress;
-static jfieldID field_mConnectingHandsfreeRfcommChannel; /* -1 when not connected */
-static jfieldID field_mConnectingHandsfreeSocketFd;
-
-
-typedef struct {
-    int hcidev;
-    int hf_ag_rfcomm_channel;
-    int hs_ag_rfcomm_channel;
-    int hf_ag_rfcomm_sock;
-    int hs_ag_rfcomm_sock;
-} native_data_t;
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
-    return (native_data_t *)(env->GetIntField(object,
-                                                 field_mNativeData));
-}
-
-static int setup_listening_socket(int dev, int channel);
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-
-    /* in */
-    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
-    field_mHandsfreeAgRfcommChannel =
-        get_field(env, clazz, "mHandsfreeAgRfcommChannel", "I");
-    field_mHeadsetAgRfcommChannel =
-        get_field(env, clazz, "mHeadsetAgRfcommChannel", "I");
-
-    /* out */
-    field_mConnectingHeadsetAddress =
-        get_field(env, clazz,
-                  "mConnectingHeadsetAddress", "Ljava/lang/String;");
-    field_mConnectingHeadsetRfcommChannel =
-        get_field(env, clazz, "mConnectingHeadsetRfcommChannel", "I");
-    field_mConnectingHeadsetSocketFd =
-        get_field(env, clazz, "mConnectingHeadsetSocketFd", "I");
-
-    field_mConnectingHandsfreeAddress =
-        get_field(env, clazz,
-                  "mConnectingHandsfreeAddress", "Ljava/lang/String;");
-    field_mConnectingHandsfreeRfcommChannel =
-        get_field(env, clazz, "mConnectingHandsfreeRfcommChannel", "I");
-    field_mConnectingHandsfreeSocketFd =
-        get_field(env, clazz, "mConnectingHandsfreeSocketFd", "I");
-
-    field_mTimeoutRemainingMs =
-        get_field(env, clazz, "mTimeoutRemainingMs", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
-    if (NULL == nat) {
-        ALOGE("%s: out of memory!", __FUNCTION__);
-        return;
-    }
-
-    nat->hcidev = BLUETOOTH_ADAPTER_HCI_NUM;
-
-    env->SetIntField(object, field_mNativeData, (jint)nat);
-    nat->hf_ag_rfcomm_channel =
-        env->GetIntField(object, field_mHandsfreeAgRfcommChannel);
-    nat->hs_ag_rfcomm_channel =
-        env->GetIntField(object, field_mHeadsetAgRfcommChannel);
-    ALOGV("HF RFCOMM channel = %d.", nat->hf_ag_rfcomm_channel);
-    ALOGV("HS RFCOMM channel = %d.", nat->hs_ag_rfcomm_channel);
-
-    /* Set the default values of these to -1. */
-    env->SetIntField(object, field_mConnectingHeadsetRfcommChannel, -1);
-    env->SetIntField(object, field_mConnectingHandsfreeRfcommChannel, -1);
-
-    nat->hf_ag_rfcomm_sock = -1;
-    nat->hs_ag_rfcomm_sock = -1;
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        free(nat);
-    }
-#endif
-}
-
-#ifdef HAVE_BLUETOOTH
-
-#if USE_ACCEPT_DIRECTLY==0
-static int set_nb(int sk, bool nb) {
-    int flags = fcntl(sk, F_GETFL);
-    if (flags < 0) {
-        ALOGE("Can't get socket flags with fcntl(): %s (%d)",
-             strerror(errno), errno);
-        close(sk);
-        return -1;
-    }
-    flags &= ~O_NONBLOCK;
-    if (nb) flags |= O_NONBLOCK;
-    int status = fcntl(sk, F_SETFL, flags);
-    if (status < 0) {
-        ALOGE("Can't set socket to nonblocking mode with fcntl(): %s (%d)",
-             strerror(errno), errno);
-        close(sk);
-        return -1;
-    }
-    return 0;
-}
-#endif /*USE_ACCEPT_DIRECTLY==0*/
-
-static int do_accept(JNIEnv* env, jobject object, int ag_fd,
-                     jfieldID out_fd,
-                     jfieldID out_address,
-                     jfieldID out_channel) {
-
-#if USE_ACCEPT_DIRECTLY==0
-    if (set_nb(ag_fd, true) < 0)
-        return -1;
-#endif
-
-    struct sockaddr_rc raddr;
-    int alen = sizeof(raddr);
-    int nsk = TEMP_FAILURE_RETRY(accept(ag_fd, (struct sockaddr *) &raddr, &alen));
-    if (nsk < 0) {
-        ALOGE("Error on accept from socket fd %d: %s (%d).",
-             ag_fd,
-             strerror(errno),
-             errno);
-#if USE_ACCEPT_DIRECTLY==0
-        set_nb(ag_fd, false);
-#endif
-        return -1;
-    }
-
-    env->SetIntField(object, out_fd, nsk);
-    env->SetIntField(object, out_channel, raddr.rc_channel);
-
-    char addr[BTADDR_SIZE];
-    get_bdaddr_as_string(&raddr.rc_bdaddr, addr);
-    env->SetObjectField(object, out_address, env->NewStringUTF(addr));
-
-    ALOGI("Successful accept() on AG socket %d: new socket %d, address %s, RFCOMM channel %d",
-         ag_fd,
-         nsk,
-         addr,
-         raddr.rc_channel);
-#if USE_ACCEPT_DIRECTLY==0
-    set_nb(ag_fd, false);
-#endif
-    return 0;
-}
-
-#if USE_SELECT
-static inline int on_accept_set_fields(JNIEnv* env, jobject object,
-                                       fd_set *rset, int ag_fd,
-                                       jfieldID out_fd,
-                                       jfieldID out_address,
-                                       jfieldID out_channel) {
-
-    env->SetIntField(object, out_channel, -1);
-
-    if (ag_fd >= 0 && FD_ISSET(ag_fd, &rset)) {
-        return do_accept(env, object, ag_fd,
-                         out_fd, out_address, out_channel);
-    }
-    else {
-        ALOGI("fd = %d, FD_ISSET() = %d",
-             ag_fd,
-             FD_ISSET(ag_fd, &rset));
-        if (ag_fd >= 0 && !FD_ISSET(ag_fd, &rset)) {
-            ALOGE("WTF???");
-            return -1;
-        }
-    }
-
-    return 0;
-}
-#endif
-#endif /* HAVE_BLUETOOTH */
-
-static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
-                                              jint timeout_ms) {
-//    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-
-    env->SetIntField(object, field_mTimeoutRemainingMs, timeout_ms);
-
-    int n = 0;
-    native_data_t *nat = get_native_data(env, object);
-#if USE_ACCEPT_DIRECTLY
-    if (nat->hf_ag_rfcomm_channel > 0) {
-        ALOGI("Setting HF AG server socket to RFCOMM port %d!",
-             nat->hf_ag_rfcomm_channel);
-        struct timeval tv;
-        int len = sizeof(tv);
-        if (getsockopt(nat->hf_ag_rfcomm_channel,
-                       SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
-            ALOGE("getsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
-                 nat->hf_ag_rfcomm_channel,
-                 strerror(errno),
-                 errno);
-            return JNI_FALSE;
-        }
-        ALOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
-             (int)tv.tv_sec, (int)tv.tv_usec);
-        if (timeout_ms >= 0) {
-            tv.tv_sec = timeout_ms / 1000;
-            tv.tv_usec = 1000 * (timeout_ms % 1000);
-            if (setsockopt(nat->hf_ag_rfcomm_channel,
-                           SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
-                ALOGE("setsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
-                     nat->hf_ag_rfcomm_channel,
-                     strerror(errno),
-                     errno);
-                return JNI_FALSE;
-            }
-            ALOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
-                 (int)tv.tv_sec, (int)tv.tv_usec);
-        }
-
-        if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
-                       field_mConnectingHandsfreeSocketFd,
-                       field_mConnectingHandsfreeAddress,
-                       field_mConnectingHandsfreeRfcommChannel))
-        {
-            env->SetIntField(object, field_mTimeoutRemainingMs, 0);
-            return JNI_TRUE;
-        }
-        return JNI_FALSE;
-    }
-#else
-#if USE_SELECT
-    fd_set rset;
-    FD_ZERO(&rset);
-    int cnt = 0;
-    if (nat->hf_ag_rfcomm_channel > 0) {
-        ALOGI("Setting HF AG server socket to RFCOMM port %d!",
-             nat->hf_ag_rfcomm_channel);
-        cnt++;
-        FD_SET(nat->hf_ag_rfcomm_sock, &rset);
-    }
-    if (nat->hs_ag_rfcomm_channel > 0) {
-        ALOGI("Setting HS AG server socket to RFCOMM port %d!",
-             nat->hs_ag_rfcomm_channel);
-        cnt++;
-        FD_SET(nat->hs_ag_rfcomm_sock, &rset);
-    }
-    if (cnt == 0) {
-        ALOGE("Neither HF nor HS listening sockets are open!");
-        return JNI_FALSE;
-    }
-
-    struct timeval to;
-    if (timeout_ms >= 0) {
-        to.tv_sec = timeout_ms / 1000;
-        to.tv_usec = 1000 * (timeout_ms % 1000);
-    }
-    n = TEMP_FAILURE_RETRY(select(
-                   MAX(nat->hf_ag_rfcomm_sock, nat->hs_ag_rfcomm_sock) + 1,
-                   &rset,
-                   NULL,
-                   NULL,
-                   (timeout_ms < 0 ? NULL : &to)));
-    if (timeout_ms > 0) {
-        jint remaining = to.tv_sec*1000 + to.tv_usec/1000;
-        ALOGI("Remaining time %ldms", (long)remaining);
-        env->SetIntField(object, field_mTimeoutRemainingMs,
-                         remaining);
-    }
-
-    ALOGI("listening select() returned %d", n);
-
-    if (n <= 0) {
-        if (n < 0)  {
-            ALOGE("listening select() on RFCOMM sockets: %s (%d)",
-                 strerror(errno),
-                 errno);
-        }
-        return JNI_FALSE;
-    }
-
-    n = on_accept_set_fields(env, object,
-                             &rset, nat->hf_ag_rfcomm_sock,
-                             field_mConnectingHandsfreeSocketFd,
-                             field_mConnectingHandsfreeAddress,
-                             field_mConnectingHandsfreeRfcommChannel);
-
-    n += on_accept_set_fields(env, object,
-                              &rset, nat->hs_ag_rfcomm_sock,
-                              field_mConnectingHeadsetSocketFd,
-                              field_mConnectingHeadsetAddress,
-                              field_mConnectingHeadsetRfcommChannel);
-
-    return !n ? JNI_TRUE : JNI_FALSE;
-#else
-    struct pollfd fds[2];
-    int cnt = 0;
-    if (nat->hf_ag_rfcomm_channel > 0) {
-//        ALOGI("Setting HF AG server socket %d to RFCOMM port %d!",
-//             nat->hf_ag_rfcomm_sock,
-//             nat->hf_ag_rfcomm_channel);
-        fds[cnt].fd = nat->hf_ag_rfcomm_sock;
-        fds[cnt].events = POLLIN | POLLPRI | POLLOUT | POLLERR;
-        cnt++;
-    }
-    if (nat->hs_ag_rfcomm_channel > 0) {
-//        ALOGI("Setting HS AG server socket %d to RFCOMM port %d!",
-//             nat->hs_ag_rfcomm_sock,
-//             nat->hs_ag_rfcomm_channel);
-        fds[cnt].fd = nat->hs_ag_rfcomm_sock;
-        fds[cnt].events = POLLIN | POLLPRI | POLLOUT | POLLERR;
-        cnt++;
-    }
-    if (cnt == 0) {
-        ALOGE("Neither HF nor HS listening sockets are open!");
-        return JNI_FALSE;
-    }
-    n = TEMP_FAILURE_RETRY(poll(fds, cnt, timeout_ms));
-    if (n <= 0) {
-        if (n < 0)  {
-            ALOGE("listening poll() on RFCOMM sockets: %s (%d)",
-                 strerror(errno),
-                 errno);
-        }
-        else {
-            env->SetIntField(object, field_mTimeoutRemainingMs, 0);
-//            ALOGI("listening poll() on RFCOMM socket timed out");
-        }
-        return JNI_FALSE;
-    }
-
-    //ALOGI("listening poll() on RFCOMM socket returned %d", n);
-    int err = 0;
-    for (cnt = 0; cnt < (int)(sizeof(fds)/sizeof(fds[0])); cnt++) {
-        //ALOGI("Poll on fd %d revent = %d.", fds[cnt].fd, fds[cnt].revents);
-        if (fds[cnt].fd == nat->hf_ag_rfcomm_sock) {
-            if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
-                ALOGI("Accepting HF connection.\n");
-                err += do_accept(env, object, fds[cnt].fd,
-                               field_mConnectingHandsfreeSocketFd,
-                               field_mConnectingHandsfreeAddress,
-                               field_mConnectingHandsfreeRfcommChannel);
-                n--;
-            }
-        }
-        else if (fds[cnt].fd == nat->hs_ag_rfcomm_sock) {
-            if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
-                ALOGI("Accepting HS connection.\n");
-                err += do_accept(env, object, fds[cnt].fd,
-                               field_mConnectingHeadsetSocketFd,
-                               field_mConnectingHeadsetAddress,
-                               field_mConnectingHeadsetRfcommChannel);
-                n--;
-            }
-        }
-    } /* for */
-
-    if (n != 0) {
-        ALOGI("Bogus poll(): %d fake pollfd entrie(s)!", n);
-        return JNI_FALSE;
-    }
-
-    return !err ? JNI_TRUE : JNI_FALSE;
-#endif /* USE_SELECT */
-#endif /* USE_ACCEPT_DIRECTLY */
-#else
-    return JNI_FALSE;
-#endif /* HAVE_BLUETOOTH */
-}
-
-static jboolean setUpListeningSocketsNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-
-    nat->hf_ag_rfcomm_sock =
-        setup_listening_socket(nat->hcidev, nat->hf_ag_rfcomm_channel);
-    if (nat->hf_ag_rfcomm_sock < 0)
-        return JNI_FALSE;
-
-    nat->hs_ag_rfcomm_sock =
-        setup_listening_socket(nat->hcidev, nat->hs_ag_rfcomm_channel);
-    if (nat->hs_ag_rfcomm_sock < 0) {
-        close(nat->hf_ag_rfcomm_sock);
-        nat->hf_ag_rfcomm_sock = -1;
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-#else
-    return JNI_FALSE;
-#endif /* HAVE_BLUETOOTH */
-}
-
-#ifdef HAVE_BLUETOOTH
-static int setup_listening_socket(int dev, int channel) {
-    struct sockaddr_rc laddr;
-    int sk, lm;
-
-    sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-    if (sk < 0) {
-        ALOGE("Can't create RFCOMM socket");
-        return -1;
-    }
-
-    if (debug_no_encrypt()) {
-        lm = RFCOMM_LM_AUTH;
-    } else {
-        lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
-    }
-
-    if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
-        ALOGE("Can't set RFCOMM link mode");
-        close(sk);
-        return -1;
-    }
-
-    laddr.rc_family = AF_BLUETOOTH;
-    bdaddr_t any = android_bluetooth_bdaddr_any();
-    memcpy(&laddr.rc_bdaddr, &any, sizeof(bdaddr_t));
-    laddr.rc_channel = channel;
-
-    if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
-        ALOGE("Can't bind RFCOMM socket");
-        close(sk);
-        return -1;
-    }
-
-    listen(sk, 10);
-    return sk;
-}
-#endif /* HAVE_BLUETOOTH */
-
-/*
-    private native void tearDownListeningSocketsNative();
-*/
-static void tearDownListeningSocketsNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-
-    if (nat->hf_ag_rfcomm_sock > 0) {
-        if (close(nat->hf_ag_rfcomm_sock) < 0) {
-            ALOGE("Could not close HF server socket: %s (%d)\n",
-                 strerror(errno), errno);
-        }
-        nat->hf_ag_rfcomm_sock = -1;
-    }
-    if (nat->hs_ag_rfcomm_sock > 0) {
-        if (close(nat->hs_ag_rfcomm_sock) < 0) {
-            ALOGE("Could not close HS server socket: %s (%d)\n",
-                 strerror(errno), errno);
-        }
-        nat->hs_ag_rfcomm_sock = -1;
-    }
-#endif /* HAVE_BLUETOOTH */
-}
-
-static JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-
-    {"classInitNative", "()V", (void*)classInitNative},
-    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
-    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
-
-    {"setUpListeningSocketsNative", "()Z", (void *)setUpListeningSocketsNative},
-    {"tearDownListeningSocketsNative", "()V", (void *)tearDownListeningSocketsNative},
-    {"waitForHandsfreeConnectNative", "(I)Z", (void *)waitForHandsfreeConnectNative},
-};
-
-int register_android_bluetooth_BluetoothAudioGateway(JNIEnv *env) {
-    return AndroidRuntime::registerNativeMethods(env,
-            "android/bluetooth/BluetoothAudioGateway", sMethods,
-            NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
deleted file mode 100644
index d9ff36a..0000000
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BluetoothSocket.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_bluetooth_c.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "utils/Log.h"
-#include "cutils/abort_socket.h"
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/l2cap.h>
-#include <bluetooth/sco.h>
-#endif
-
-#define TYPE_AS_STR(t) \
-    ((t) == TYPE_RFCOMM ? "RFCOMM" : ((t) == TYPE_SCO ? "SCO" : "L2CAP"))
-
-namespace android {
-
-static jfieldID  field_mAuth;     /* read-only */
-static jfieldID  field_mEncrypt;  /* read-only */
-static jfieldID  field_mType;     /* read-only */
-static jfieldID  field_mAddress;  /* read-only */
-static jfieldID  field_mPort;     /* read-only */
-static jfieldID  field_mSocketData;
-static jmethodID method_BluetoothSocket_ctor;
-static jclass    class_BluetoothSocket;
-
-/* Keep TYPE_RFCOMM etc in sync with BluetoothSocket.java */
-static const int TYPE_RFCOMM = 1;
-static const int TYPE_SCO = 2;
-static const int TYPE_L2CAP = 3;  // TODO: Test l2cap code paths
-
-static const int RFCOMM_SO_SNDBUF = 70 * 1024;  // 70 KB send buffer
-
-static void abortNative(JNIEnv *env, jobject obj);
-static void destroyNative(JNIEnv *env, jobject obj);
-
-static struct asocket *get_socketData(JNIEnv *env, jobject obj) {
-    struct asocket *s =
-            (struct asocket *) env->GetIntField(obj, field_mSocketData);
-    if (!s)
-        jniThrowException(env, "java/io/IOException", "null socketData");
-    return s;
-}
-
-static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    struct asocket *s = asocket_init(fd);
-
-    if (!s) {
-        ALOGV("asocket_init() failed, throwing");
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    env->SetIntField(obj, field_mSocketData, (jint)s);
-
-    return;
-#endif
-    jniThrowIOException(env, ENOSYS);
-}
-
-static void initSocketNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int fd;
-    int lm = 0;
-    int sndbuf;
-    jboolean auth;
-    jboolean encrypt;
-    jint type;
-
-    type = env->GetIntField(obj, field_mType);
-
-    switch (type) {
-    case TYPE_RFCOMM:
-        fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-        break;
-    case TYPE_SCO:
-        fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
-        break;
-    case TYPE_L2CAP:
-        fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
-        break;
-    default:
-        jniThrowIOException(env, ENOSYS);
-        return;
-    }
-
-    if (fd < 0) {
-        ALOGV("socket() failed, throwing");
-        jniThrowIOException(env, errno);
-        return;
-    }
-
-    auth = env->GetBooleanField(obj, field_mAuth);
-    encrypt = env->GetBooleanField(obj, field_mEncrypt);
-
-    /* kernel does not yet support LM for SCO */
-    switch (type) {
-    case TYPE_RFCOMM:
-        lm |= auth ? RFCOMM_LM_AUTH : 0;
-        lm |= encrypt ? RFCOMM_LM_ENCRYPT : 0;
-        lm |= (auth && encrypt) ? RFCOMM_LM_SECURE : 0;
-        break;
-    case TYPE_L2CAP:
-        lm |= auth ? L2CAP_LM_AUTH : 0;
-        lm |= encrypt ? L2CAP_LM_ENCRYPT : 0;
-        lm |= (auth && encrypt) ? L2CAP_LM_SECURE : 0;
-        break;
-    }
-
-    if (lm) {
-        if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
-            ALOGV("setsockopt(RFCOMM_LM) failed, throwing");
-            jniThrowIOException(env, errno);
-            return;
-        }
-    }
-
-    if (type == TYPE_RFCOMM) {
-        sndbuf = RFCOMM_SO_SNDBUF;
-        if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
-            ALOGV("setsockopt(SO_SNDBUF) failed, throwing");
-            jniThrowIOException(env, errno);
-            return;
-        }
-    }
-
-    ALOGV("...fd %d created (%s, lm = %x)", fd, TYPE_AS_STR(type), lm);
-
-    initSocketFromFdNative(env, obj, fd);
-    return;
-#endif
-    jniThrowIOException(env, ENOSYS);
-}
-
-static void connectNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int ret;
-    jint type;
-    const char *c_address;
-    jstring address;
-    bdaddr_t bdaddress;
-    socklen_t addr_sz;
-    struct sockaddr *addr;
-    struct asocket *s = get_socketData(env, obj);
-    int retry = 0;
-
-    if (!s)
-        return;
-
-    type = env->GetIntField(obj, field_mType);
-
-    /* parse address into bdaddress */
-    address = (jstring) env->GetObjectField(obj, field_mAddress);
-    c_address = env->GetStringUTFChars(address, NULL);
-    if (get_bdaddr(c_address, &bdaddress)) {
-        env->ReleaseStringUTFChars(address, c_address);
-        jniThrowIOException(env, EINVAL);
-        return;
-    }
-    env->ReleaseStringUTFChars(address, c_address);
-
-    switch (type) {
-    case TYPE_RFCOMM:
-        struct sockaddr_rc addr_rc;
-        addr = (struct sockaddr *)&addr_rc;
-        addr_sz = sizeof(addr_rc);
-
-        memset(addr, 0, addr_sz);
-        addr_rc.rc_family = AF_BLUETOOTH;
-        addr_rc.rc_channel = env->GetIntField(obj, field_mPort);
-        memcpy(&addr_rc.rc_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
-        break;
-    case TYPE_SCO:
-        struct sockaddr_sco addr_sco;
-        addr = (struct sockaddr *)&addr_sco;
-        addr_sz = sizeof(addr_sco);
-
-        memset(addr, 0, addr_sz);
-        addr_sco.sco_family = AF_BLUETOOTH;
-        memcpy(&addr_sco.sco_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
-        break;
-    case TYPE_L2CAP:
-        struct sockaddr_l2 addr_l2;
-        addr = (struct sockaddr *)&addr_l2;
-        addr_sz = sizeof(addr_l2);
-
-        memset(addr, 0, addr_sz);
-        addr_l2.l2_family = AF_BLUETOOTH;
-        addr_l2.l2_psm = env->GetIntField(obj, field_mPort);
-        memcpy(&addr_l2.l2_bdaddr, &bdaddress, sizeof(bdaddr_t));
-
-        break;
-    default:
-        jniThrowIOException(env, ENOSYS);
-        return;
-    }
-
-connect:
-    ret = asocket_connect(s, addr, addr_sz, -1);
-    ALOGV("...connect(%d, %s) = %d (errno %d)",
-            s->fd, TYPE_AS_STR(type), ret, errno);
-
-    if (ret && errno == EALREADY && retry < 2) {
-        /* workaround for bug 5082381 (EALREADY on ACL collision):
-         * retry the connect. Unfortunately we have to create a new fd.
-         * It's not ideal to switch the fd underneath the object, but
-         * is currently safe */
-        ALOGD("Hit bug 5082381 (EALREADY on ACL collision), trying workaround");
-        usleep(100000);
-        retry++;
-        abortNative(env, obj);
-        destroyNative(env, obj);
-        initSocketNative(env, obj);
-        if (env->ExceptionOccurred()) {
-            return;
-        }
-        goto connect;
-    }
-    if (!ret && retry > 0)
-        ALOGD("...workaround ok");
-
-    if (ret)
-        jniThrowIOException(env, errno);
-
-    return;
-#endif
-    jniThrowIOException(env, ENOSYS);
-}
-
-/* Returns errno instead of throwing, so java can check errno */
-static int bindListenNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    jint type;
-    socklen_t addr_sz;
-    struct sockaddr *addr;
-    bdaddr_t bdaddr = android_bluetooth_bdaddr_any();
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return EINVAL;
-
-    type = env->GetIntField(obj, field_mType);
-
-    switch (type) {
-    case TYPE_RFCOMM:
-        struct sockaddr_rc addr_rc;
-        addr = (struct sockaddr *)&addr_rc;
-        addr_sz = sizeof(addr_rc);
-
-        memset(addr, 0, addr_sz);
-        addr_rc.rc_family = AF_BLUETOOTH;
-        addr_rc.rc_channel = env->GetIntField(obj, field_mPort);
-        memcpy(&addr_rc.rc_bdaddr, &bdaddr, sizeof(bdaddr_t));
-        break;
-    case TYPE_SCO:
-        struct sockaddr_sco addr_sco;
-        addr = (struct sockaddr *)&addr_sco;
-        addr_sz = sizeof(addr_sco);
-
-        memset(addr, 0, addr_sz);
-        addr_sco.sco_family = AF_BLUETOOTH;
-        memcpy(&addr_sco.sco_bdaddr, &bdaddr, sizeof(bdaddr_t));
-        break;
-    case TYPE_L2CAP:
-        struct sockaddr_l2 addr_l2;
-        addr = (struct sockaddr *)&addr_l2;
-        addr_sz = sizeof(addr_l2);
-
-        memset(addr, 0, addr_sz);
-        addr_l2.l2_family = AF_BLUETOOTH;
-        addr_l2.l2_psm = env->GetIntField(obj, field_mPort);
-        memcpy(&addr_l2.l2_bdaddr, &bdaddr, sizeof(bdaddr_t));
-        break;
-    default:
-        return ENOSYS;
-    }
-
-    if (bind(s->fd, addr, addr_sz)) {
-        ALOGV("...bind(%d) gave errno %d", s->fd, errno);
-        return errno;
-    }
-
-    if (listen(s->fd, 1)) {
-        ALOGV("...listen(%d) gave errno %d", s->fd, errno);
-        return errno;
-    }
-
-    ALOGV("...bindListenNative(%d) success", s->fd);
-
-    return 0;
-
-#endif
-    return ENOSYS;
-}
-
-static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int fd;
-    jint type;
-    struct sockaddr *addr;
-    socklen_t addr_sz;
-    jstring addr_jstr;
-    char addr_cstr[BTADDR_SIZE];
-    bdaddr_t *bdaddr;
-    jboolean auth;
-    jboolean encrypt;
-
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return NULL;
-
-    type = env->GetIntField(obj, field_mType);
-
-    switch (type) {
-    case TYPE_RFCOMM:
-        struct sockaddr_rc addr_rc;
-        addr = (struct sockaddr *)&addr_rc;
-        addr_sz = sizeof(addr_rc);
-        bdaddr = &addr_rc.rc_bdaddr;
-        memset(addr, 0, addr_sz);
-        break;
-    case TYPE_SCO:
-        struct sockaddr_sco addr_sco;
-        addr = (struct sockaddr *)&addr_sco;
-        addr_sz = sizeof(addr_sco);
-        bdaddr = &addr_sco.sco_bdaddr;
-        memset(addr, 0, addr_sz);
-        break;
-    case TYPE_L2CAP:
-        struct sockaddr_l2 addr_l2;
-        addr = (struct sockaddr *)&addr_l2;
-        addr_sz = sizeof(addr_l2);
-        bdaddr = &addr_l2.l2_bdaddr;
-        memset(addr, 0, addr_sz);
-        break;
-    default:
-        jniThrowIOException(env, ENOSYS);
-        return NULL;
-    }
-
-    fd = asocket_accept(s, addr, &addr_sz, timeout);
-
-    ALOGV("...accept(%d, %s) = %d (errno %d)",
-            s->fd, TYPE_AS_STR(type), fd, errno);
-
-    if (fd < 0) {
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    /* Connected - return new BluetoothSocket */
-    auth = env->GetBooleanField(obj, field_mAuth);
-    encrypt = env->GetBooleanField(obj, field_mEncrypt);
-
-    get_bdaddr_as_string(bdaddr, addr_cstr);
-
-    addr_jstr = env->NewStringUTF(addr_cstr);
-    return env->NewObject(class_BluetoothSocket, method_BluetoothSocket_ctor,
-            type, fd, auth, encrypt, addr_jstr, -1);
-
-#endif
-    jniThrowIOException(env, ENOSYS);
-    return NULL;
-}
-
-static jint availableNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int available;
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return -1;
-
-    if (ioctl(s->fd, FIONREAD, &available) < 0) {
-        jniThrowIOException(env, errno);
-        return -1;
-    }
-
-    return available;
-
-#endif
-    jniThrowIOException(env, ENOSYS);
-    return -1;
-}
-
-static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
-        jint length) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int ret;
-    jbyte *b;
-    int sz;
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return -1;
-    if (jb == NULL) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-    sz = env->GetArrayLength(jb);
-    if (offset < 0 || length < 0 || offset + length > sz) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-
-    b = env->GetByteArrayElements(jb, NULL);
-    if (b == NULL) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-
-    ret = asocket_read(s, &b[offset], length, -1);
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
-        return -1;
-    }
-
-    env->ReleaseByteArrayElements(jb, b, 0);
-    return (jint)ret;
-
-#endif
-    jniThrowIOException(env, ENOSYS);
-    return -1;
-}
-
-static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
-        jint length) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-
-    int ret, total;
-    jbyte *b;
-    int sz;
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return -1;
-    if (jb == NULL) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-    sz = env->GetArrayLength(jb);
-    if (offset < 0 || length < 0 || offset + length > sz) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-
-    b = env->GetByteArrayElements(jb, NULL);
-    if (b == NULL) {
-        jniThrowIOException(env, EINVAL);
-        return -1;
-    }
-
-    total = 0;
-    while (length > 0) {
-        ret = asocket_write(s, &b[offset], length, -1);
-        if (ret < 0) {
-            jniThrowIOException(env, errno);
-            env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
-            return -1;
-        }
-        offset += ret;
-        total += ret;
-        length -= ret;
-    }
-
-    env->ReleaseByteArrayElements(jb, b, JNI_ABORT);  // no need to commit
-    return (jint)total;
-
-#endif
-    jniThrowIOException(env, ENOSYS);
-    return -1;
-}
-
-static void abortNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    struct asocket *s = get_socketData(env, obj);
-
-    if (!s)
-        return;
-
-    asocket_abort(s);
-
-    ALOGV("...asocket_abort(%d) complete", s->fd);
-    return;
-#endif
-    jniThrowIOException(env, ENOSYS);
-}
-
-static void destroyNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    struct asocket *s = get_socketData(env, obj);
-    int fd = s->fd;
-
-    if (!s)
-        return;
-
-    asocket_destroy(s);
-
-    ALOGV("...asocket_destroy(%d) complete", fd);
-    return;
-#endif
-    jniThrowIOException(env, ENOSYS);
-}
-
-static void throwErrnoNative(JNIEnv *env, jobject obj, jint err) {
-    jniThrowIOException(env, err);
-}
-
-static JNINativeMethod sMethods[] = {
-    {"initSocketNative", "()V",  (void*) initSocketNative},
-    {"initSocketFromFdNative", "(I)V",  (void*) initSocketFromFdNative},
-    {"connectNative", "()V", (void *) connectNative},
-    {"bindListenNative", "()I", (void *) bindListenNative},
-    {"acceptNative", "(I)Landroid/bluetooth/BluetoothSocket;", (void *) acceptNative},
-    {"availableNative", "()I",    (void *) availableNative},
-    {"readNative", "([BII)I",    (void *) readNative},
-    {"writeNative", "([BII)I",    (void *) writeNative},
-    {"abortNative", "()V",    (void *) abortNative},
-    {"destroyNative", "()V",    (void *) destroyNative},
-    {"throwErrnoNative", "(I)V",    (void *) throwErrnoNative},
-};
-
-int register_android_bluetooth_BluetoothSocket(JNIEnv *env) {
-    jclass clazz = env->FindClass("android/bluetooth/BluetoothSocket");
-    if (clazz == NULL)
-        return -1;
-    class_BluetoothSocket = (jclass) env->NewGlobalRef(clazz);
-    field_mType = env->GetFieldID(clazz, "mType", "I");
-    field_mAddress = env->GetFieldID(clazz, "mAddress", "Ljava/lang/String;");
-    field_mPort = env->GetFieldID(clazz, "mPort", "I");
-    field_mAuth = env->GetFieldID(clazz, "mAuth", "Z");
-    field_mEncrypt = env->GetFieldID(clazz, "mEncrypt", "Z");
-    field_mSocketData = env->GetFieldID(clazz, "mSocketData", "I");
-    method_BluetoothSocket_ctor = env->GetMethodID(clazz, "<init>", "(IIZZLjava/lang/String;I)V");
-    return AndroidRuntime::registerNativeMethods(env,
-        "android/bluetooth/BluetoothSocket", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
-
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
deleted file mode 100644
index 34447ef..0000000
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BT HSHFP"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sco.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
-static jfieldID field_mAddress;
-static jfieldID field_mRfcommChannel;
-static jfieldID field_mTimeoutRemainingMs;
-
-typedef struct {
-    jstring address;
-    const char *c_address;
-    int rfcomm_channel;
-    int last_read_err;
-    int rfcomm_sock;
-    int rfcomm_connected; // -1 in progress, 0 not connected, 1 connected
-    int rfcomm_sock_flags;
-} native_data_t;
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
-    return (native_data_t *)(env->GetIntField(object, field_mNativeData));
-}
-
-static const char CRLF[] = "\xd\xa";
-static const int CRLF_LEN = 2;
-
-static inline int write_error_check(int fd, const char* line, int len) {
-    int ret;
-    errno = 0;
-    ret = write(fd, line, len);
-    if (ret < 0) {
-        ALOGE("%s: write() failed: %s (%d)", __FUNCTION__, strerror(errno),
-             errno);
-        return -1;
-    }
-    if (ret != len) {
-        ALOGE("%s: write() only wrote %d of %d bytes", __FUNCTION__, ret, len);
-        return -1;
-    }
-    return 0;
-}
-
-static int send_line(int fd, const char* line) {
-    int nw;
-    int len = strlen(line);
-    int llen = len + CRLF_LEN * 2 + 1;
-    char *buffer = (char *)calloc(llen, sizeof(char));
-
-    snprintf(buffer, llen, "%s%s%s", CRLF, line, CRLF);
-
-    if (write_error_check(fd, buffer, llen - 1)) {
-        free(buffer);
-        return -1;
-    }
-    free(buffer);
-    return 0;
-}
-
-static void mask_eighth_bit(char *line)
-{
-   for (;;line++) {
-     if (0 == *line) return;
-     *line &= 0x7F;
-   }
-}
-
-static const char* get_line(int fd, char *buf, int len, int timeout_ms,
-                            int *err) {
-    char *bufit=buf;
-    int fd_flags = fcntl(fd, F_GETFL, 0);
-    struct pollfd pfd;
-
-again:
-    *bufit = 0;
-    pfd.fd = fd;
-    pfd.events = POLLIN;
-    *err = errno = 0;
-    int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, timeout_ms));
-    if (ret < 0) {
-        ALOGE("poll() error\n");
-        *err = errno;
-        return NULL;
-    }
-    if (ret == 0) {
-        return NULL;
-    }
-
-    if (pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) {
-        ALOGW("RFCOMM poll() returned  success (%d), "
-             "but with an unexpected revents bitmask: %#x\n", ret, pfd.revents);
-        errno = EIO;
-        *err = errno;
-        return NULL;
-    }
-
-    while ((int)(bufit - buf) < (len - 1))
-    {
-        errno = 0;
-        int rc = TEMP_FAILURE_RETRY(read(fd, bufit, 1));
-
-        if (!rc)
-            break;
-
-        if (rc < 0) {
-            if (errno == EBUSY) {
-                ALOGI("read() error %s (%d): repeating read()...",
-                     strerror(errno), errno);
-                goto again;
-            }
-            *err = errno;
-            ALOGE("read() error %s (%d)", strerror(errno), errno);
-            return NULL;
-        }
-
-
-        if (*bufit=='\xd') {
-            break;
-        }
-
-        if (*bufit=='\xa')
-            bufit = buf;
-        else
-            bufit++;
-    }
-
-    *bufit = 0;
-
-    // According to ITU V.250 section 5.1, IA5 7 bit chars are used, 
-    //   the eighth bit or higher bits are ignored if they exists
-    // We mask out only eighth bit, no higher bit, since we do char
-    // string here, not wide char.
-    // We added this processing due to 2 real world problems.
-    // 1 BMW 2005 E46 which sends binary junk
-    // 2 Audi 2010 A3, dial command use 0xAD (soft-hyphen) as number 
-    //   formater, which was rejected by the AT handler
-    mask_eighth_bit(buf);
-
-    return buf;
-}
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
-    field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
-    field_mTimeoutRemainingMs = get_field(env, clazz, "mTimeoutRemainingMs", "I");
-    field_mRfcommChannel = get_field(env, clazz, "mRfcommChannel", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object,
-                                       jint socketFd) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
-    if (NULL == nat) {
-        ALOGE("%s: out of memory!", __FUNCTION__);
-        return;
-    }
-
-    env->SetIntField(object, field_mNativeData, (jint)nat);
-    nat->address =
-        (jstring)env->NewGlobalRef(env->GetObjectField(object,
-                                                       field_mAddress));
-    nat->c_address = env->GetStringUTFChars(nat->address, NULL);
-    nat->rfcomm_channel = env->GetIntField(object, field_mRfcommChannel);
-    nat->rfcomm_sock = socketFd;
-    nat->rfcomm_connected = socketFd >= 0;
-    if (nat->rfcomm_connected)
-        ALOGI("%s: ALREADY CONNECTED!", __FUNCTION__);
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat =
-        (native_data_t *)env->GetIntField(object, field_mNativeData);
-    env->ReleaseStringUTFChars(nat->address, nat->c_address);
-    env->DeleteGlobalRef(nat->address);
-    if (nat)
-        free(nat);
-#endif
-}
-
-static jboolean connectNative(JNIEnv *env, jobject obj)
-{
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    int lm;
-    struct sockaddr_rc addr;
-    native_data_t *nat = get_native_data(env, obj);
-
-    nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-
-    if (nat->rfcomm_sock < 0) {
-        ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
-             strerror(errno));
-        return JNI_FALSE;
-    }
-
-    if (debug_no_encrypt()) {
-        lm = RFCOMM_LM_AUTH;
-    } else {
-        lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
-    }
-
-    if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
-                sizeof(lm)) < 0) {
-        ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
-        close(nat->rfcomm_sock);
-        return JNI_FALSE;
-    }
-
-    memset(&addr, 0, sizeof(struct sockaddr_rc));
-    get_bdaddr(nat->c_address, &addr.rc_bdaddr);
-    addr.rc_channel = nat->rfcomm_channel;
-    addr.rc_family = AF_BLUETOOTH;
-    nat->rfcomm_connected = 0;
-    while (nat->rfcomm_connected == 0) {
-        if (connect(nat->rfcomm_sock, (struct sockaddr *)&addr,
-                      sizeof(addr)) < 0) {
-            if (errno == EINTR) continue;
-            ALOGE("%s: connect() failed: %s\n", __FUNCTION__, strerror(errno));
-            close(nat->rfcomm_sock);
-            nat->rfcomm_sock = -1;
-            return JNI_FALSE;
-        } else {
-            nat->rfcomm_connected = 1;
-        }
-    }
-
-    return JNI_TRUE;
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jint connectAsyncNative(JNIEnv *env, jobject obj) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    struct sockaddr_rc addr;
-    native_data_t *nat = get_native_data(env, obj);
-
-    if (nat->rfcomm_connected) {
-        ALOGV("RFCOMM socket is already connected or connection is in progress.");
-        return 0;
-    }
-
-    if (nat->rfcomm_sock < 0) {
-        int lm;
-
-        nat->rfcomm_sock = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-        if (nat->rfcomm_sock < 0) {
-            ALOGE("%s: Could not create RFCOMM socket: %s\n", __FUNCTION__,
-                 strerror(errno));
-            return -1;
-        }
-
-        if (debug_no_encrypt()) {
-            lm = RFCOMM_LM_AUTH;
-        } else {
-            lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
-        }
-
-        if (lm && setsockopt(nat->rfcomm_sock, SOL_RFCOMM, RFCOMM_LM, &lm,
-                    sizeof(lm)) < 0) {
-            ALOGE("%s: Can't set RFCOMM link mode", __FUNCTION__);
-            close(nat->rfcomm_sock);
-            return -1;
-        }
-        ALOGI("Created RFCOMM socket fd %d.", nat->rfcomm_sock);
-    }
-
-    memset(&addr, 0, sizeof(struct sockaddr_rc));
-    get_bdaddr(nat->c_address, &addr.rc_bdaddr);
-    addr.rc_channel = nat->rfcomm_channel;
-    addr.rc_family = AF_BLUETOOTH;
-    if (nat->rfcomm_sock_flags >= 0) {
-        nat->rfcomm_sock_flags = fcntl(nat->rfcomm_sock, F_GETFL, 0);
-        if (fcntl(nat->rfcomm_sock,
-                  F_SETFL, nat->rfcomm_sock_flags | O_NONBLOCK) >= 0) {
-            int rc;
-            nat->rfcomm_connected = 0;
-            errno = 0;
-            rc = connect(nat->rfcomm_sock,
-                        (struct sockaddr *)&addr,
-                         sizeof(addr));
-
-            if (rc >= 0) {
-                nat->rfcomm_connected = 1;
-                ALOGI("async connect successful");
-                return 0;
-            }
-            else if (rc < 0) {
-                if (errno == EINPROGRESS || errno == EAGAIN)
-                {
-                    ALOGI("async connect is in progress (%s)",
-                         strerror(errno));
-                    nat->rfcomm_connected = -1;
-                    return 0;
-                }
-                else
-                {
-                    ALOGE("async connect error: %s (%d)", strerror(errno), errno);
-                    close(nat->rfcomm_sock);
-                    nat->rfcomm_sock = -1;
-                    return -errno;
-                }
-            }
-        } // fcntl(nat->rfcomm_sock ...)
-    } // if (nat->rfcomm_sock_flags >= 0)
-#endif
-    return -1;
-}
-
-static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
-                                           jint timeout_ms) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    struct sockaddr_rc addr;
-    native_data_t *nat = get_native_data(env, obj);
-
-    env->SetIntField(obj, field_mTimeoutRemainingMs, timeout_ms);
-
-    if (nat->rfcomm_connected > 0) {
-        ALOGI("RFCOMM is already connected!");
-        return 1;
-    }
-
-    if (nat->rfcomm_sock >= 0 && nat->rfcomm_connected == 0) {
-        ALOGI("Re-opening RFCOMM socket.");
-        close(nat->rfcomm_sock);
-        nat->rfcomm_sock = -1;
-    }
-    int ret = connectAsyncNative(env, obj);
-
-    if (ret < 0) {
-        ALOGI("Failed to re-open RFCOMM socket!");
-        return ret;
-    }
-
-    if (nat->rfcomm_sock >= 0) {
-        /* Do an asynchronous select() */
-        int n;
-        fd_set rset, wset;
-        struct timeval to;
-
-        FD_ZERO(&rset);
-        FD_ZERO(&wset);
-        FD_SET(nat->rfcomm_sock, &rset);
-        FD_SET(nat->rfcomm_sock, &wset);
-        if (timeout_ms >= 0) {
-            to.tv_sec = timeout_ms / 1000;
-            to.tv_usec = 1000 * (timeout_ms % 1000);
-        }
-        n = select(nat->rfcomm_sock + 1,
-                   &rset,
-                   &wset,
-                   NULL,
-                   (timeout_ms < 0 ? NULL : &to));
-
-        if (timeout_ms > 0) {
-            jint remaining = to.tv_sec*1000 + to.tv_usec/1000;
-            ALOGV("Remaining time %ldms", (long)remaining);
-            env->SetIntField(obj, field_mTimeoutRemainingMs,
-                             remaining);
-        }
-
-        if (n <= 0) {
-            if (n < 0)  {
-                ALOGE("select() on RFCOMM socket: %s (%d)",
-                     strerror(errno),
-                     errno);
-                return -errno;
-            }
-            return 0;
-        }
-        /* n must be equal to 1 and either rset or wset must have the
-           file descriptor set. */
-        ALOGV("select() returned %d.", n);
-        if (FD_ISSET(nat->rfcomm_sock, &rset) ||
-            FD_ISSET(nat->rfcomm_sock, &wset))
-        {
-            /* A trial async read() will tell us if everything is OK. */
-            {
-                char ch;
-                errno = 0;
-                int nr = TEMP_FAILURE_RETRY(read(nat->rfcomm_sock, &ch, 1));
-                /* It should be that nr != 1 because we just opened a socket
-                   and we haven't sent anything over it for the other side to
-                   respond... but one can't be paranoid enough.
-                */
-                if (nr >= 0 || errno != EAGAIN) {
-                    ALOGE("RFCOMM async connect() error: %s (%d), nr = %d\n",
-                         strerror(errno),
-                         errno,
-                         nr);
-                    /* Clear the rfcomm_connected flag to cause this function
-                       to re-create the socket and re-attempt the connect()
-                       the next time it is called.
-                    */
-                    nat->rfcomm_connected = 0;
-                    /* Restore the blocking properties of the socket. */
-                    fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
-                    close(nat->rfcomm_sock);
-                    nat->rfcomm_sock = -1;
-                    return -errno;
-                }
-            }
-            /* Restore the blocking properties of the socket. */
-            fcntl(nat->rfcomm_sock, F_SETFL, nat->rfcomm_sock_flags);
-            ALOGI("Successful RFCOMM socket connect.");
-            nat->rfcomm_connected = 1;
-            return 1;
-        }
-    }
-    else ALOGE("RFCOMM socket file descriptor %d is bad!",
-              nat->rfcomm_sock);
-#endif
-    return -1;
-}
-
-static void disconnectNative(JNIEnv *env, jobject obj) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, obj);
-    if (nat->rfcomm_sock >= 0) {
-        close(nat->rfcomm_sock);
-        nat->rfcomm_sock = -1;
-        nat->rfcomm_connected = 0;
-    }
-#endif
-}
-
-static void pretty_log_urc(const char *urc) {
-    size_t i;
-    bool in_line_break = false;
-    char *buf = (char *)calloc(strlen(urc) + 1, sizeof(char));
-
-    strcpy(buf, urc);
-    for (i = 0; i < strlen(buf); i++) {
-        switch(buf[i]) {
-        case '\r':
-        case '\n':
-            in_line_break = true;
-            buf[i] = ' ';
-            break;
-        default:
-            if (in_line_break) {
-                in_line_break = false;
-                buf[i-1] = '\n';
-            }
-        }
-    }
-    IF_ALOGV() ALOG(LOG_VERBOSE, "Bluetooth AT sent", "%s", buf);
-
-    free(buf);
-}
-
-static jboolean sendURCNative(JNIEnv *env, jobject obj, jstring urc) {
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, obj);
-    if (nat->rfcomm_connected) {
-        const char *c_urc = env->GetStringUTFChars(urc, NULL);
-        jboolean ret = send_line(nat->rfcomm_sock, c_urc) == 0 ? JNI_TRUE : JNI_FALSE;
-        if (ret == JNI_TRUE) pretty_log_urc(c_urc);
-        env->ReleaseStringUTFChars(urc, c_urc);
-        return ret;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jstring readNative(JNIEnv *env, jobject obj, jint timeout_ms) {
-#ifdef HAVE_BLUETOOTH
-    {
-        native_data_t *nat = get_native_data(env, obj);
-        if (nat->rfcomm_connected) {
-            char buf[256];
-            const char *ret = get_line(nat->rfcomm_sock,
-                                       buf, sizeof(buf),
-                                       timeout_ms,
-                                       &nat->last_read_err);
-            return ret ? env->NewStringUTF(ret) : NULL;
-        }
-        return NULL;
-    }
-#else
-    return NULL;
-#endif
-}
-
-static jint getLastReadStatusNative(JNIEnv *env, jobject obj) {
-#ifdef HAVE_BLUETOOTH
-    {
-        native_data_t *nat = get_native_data(env, obj);
-        if (nat->rfcomm_connected)
-            return (jint)nat->last_read_err;
-        return 0;
-    }
-#else
-    return 0;
-#endif
-}
-
-static JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"classInitNative", "()V", (void*)classInitNative},
-    {"initializeNativeDataNative", "(I)V", (void *)initializeNativeDataNative},
-    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
-    {"connectNative", "()Z", (void *)connectNative},
-    {"connectAsyncNative", "()I", (void *)connectAsyncNative},
-    {"waitForAsyncConnectNative", "(I)I", (void *)waitForAsyncConnectNative},
-    {"disconnectNative", "()V", (void *)disconnectNative},
-    {"sendURCNative", "(Ljava/lang/String;)Z", (void *)sendURCNative},
-    {"readNative", "(I)Ljava/lang/String;", (void *)readNative},
-    {"getLastReadStatusNative", "()I", (void *)getLastReadStatusNative},
-};
-
-int register_android_bluetooth_HeadsetBase(JNIEnv *env) {
-    return AndroidRuntime::registerNativeMethods(env,
-            "android/bluetooth/HeadsetBase", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_c.c b/core/jni/android_bluetooth_c.c
deleted file mode 100644
index b4c6727..0000000
--- a/core/jni/android_bluetooth_c.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-** Copyright 2011, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifdef HAVE_BLUETOOTH
-
-#include "android_bluetooth_c.h"
-
-/*
- * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
- * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
- * is not valid C++ code.
- */
-bdaddr_t android_bluetooth_bdaddr_any(void)
-{
-  bdaddr_t any = *BDADDR_ANY;
-  return any;
-}
-#endif
diff --git a/core/jni/android_bluetooth_c.h b/core/jni/android_bluetooth_c.h
deleted file mode 100644
index e890244..0000000
--- a/core/jni/android_bluetooth_c.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-** Copyright 2010, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_BLUETOOTH_C_H
-#define ANDROID_BLUETOOTH_C_H
-#ifdef HAVE_BLUETOOTH
-
-#include <bluetooth/bluetooth.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
- * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
- * is not valid C++ code.
- */
-bdaddr_t android_bluetooth_bdaddr_any(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*HAVE_BLUETOOTH*/
-#endif /*ANDROID_BLUETOOTH_C_H*/
diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp
deleted file mode 100644
index 5cdaa6c..0000000
--- a/core/jni/android_bluetooth_common.cpp
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "bluetooth_common.cpp"
-
-#include "android_bluetooth_common.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <cutils/properties.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-
-static Properties remote_device_properties[] = {
-    {"Address",  DBUS_TYPE_STRING},
-    {"Name", DBUS_TYPE_STRING},
-    {"Icon", DBUS_TYPE_STRING},
-    {"Class", DBUS_TYPE_UINT32},
-    {"UUIDs", DBUS_TYPE_ARRAY},
-    {"Services", DBUS_TYPE_ARRAY},
-    {"Paired", DBUS_TYPE_BOOLEAN},
-    {"Connected", DBUS_TYPE_BOOLEAN},
-    {"Trusted", DBUS_TYPE_BOOLEAN},
-    {"Blocked", DBUS_TYPE_BOOLEAN},
-    {"Alias", DBUS_TYPE_STRING},
-    {"Nodes", DBUS_TYPE_ARRAY},
-    {"Adapter", DBUS_TYPE_OBJECT_PATH},
-    {"LegacyPairing", DBUS_TYPE_BOOLEAN},
-    {"RSSI", DBUS_TYPE_INT16},
-    {"TX", DBUS_TYPE_UINT32},
-    {"Broadcaster", DBUS_TYPE_BOOLEAN}
-};
-
-static Properties adapter_properties[] = {
-    {"Address", DBUS_TYPE_STRING},
-    {"Name", DBUS_TYPE_STRING},
-    {"Class", DBUS_TYPE_UINT32},
-    {"Powered", DBUS_TYPE_BOOLEAN},
-    {"Discoverable", DBUS_TYPE_BOOLEAN},
-    {"DiscoverableTimeout", DBUS_TYPE_UINT32},
-    {"Pairable", DBUS_TYPE_BOOLEAN},
-    {"PairableTimeout", DBUS_TYPE_UINT32},
-    {"Discovering", DBUS_TYPE_BOOLEAN},
-    {"Devices", DBUS_TYPE_ARRAY},
-    {"UUIDs", DBUS_TYPE_ARRAY},
-};
-
-static Properties input_properties[] = {
-    {"Connected", DBUS_TYPE_BOOLEAN},
-};
-
-static Properties pan_properties[] = {
-    {"Connected", DBUS_TYPE_BOOLEAN},
-    {"Interface", DBUS_TYPE_STRING},
-    {"UUID", DBUS_TYPE_STRING},
-};
-
-static Properties health_device_properties[] = {
-    {"MainChannel", DBUS_TYPE_OBJECT_PATH},
-};
-
-static Properties health_channel_properties[] = {
-    {"Type", DBUS_TYPE_STRING},
-    {"Device", DBUS_TYPE_OBJECT_PATH},
-    {"Application", DBUS_TYPE_OBJECT_PATH},
-};
-
-typedef union {
-    char *str_val;
-    int int_val;
-    char **array_val;
-} property_value;
-
-jfieldID get_field(JNIEnv *env, jclass clazz, const char *member,
-                   const char *mtype) {
-    jfieldID field = env->GetFieldID(clazz, member, mtype);
-    if (field == NULL) {
-        ALOGE("Can't find member %s", member);
-    }
-    return field;
-}
-
-typedef struct {
-    void (*user_cb)(DBusMessage *, void *, void *);
-    void *user;
-    void *nat;
-    JNIEnv *env;
-} dbus_async_call_t;
-
-void dbus_func_args_async_callback(DBusPendingCall *call, void *data) {
-
-    dbus_async_call_t *req = (dbus_async_call_t *)data;
-    DBusMessage *msg;
-
-    /* This is guaranteed to be non-NULL, because this function is called only
-       when once the remote method invokation returns. */
-    msg = dbus_pending_call_steal_reply(call);
-
-    if (msg) {
-        if (req->user_cb) {
-            // The user may not deref the message object.
-            req->user_cb(msg, req->user, req->nat);
-        }
-        dbus_message_unref(msg);
-    }
-
-    //dbus_message_unref(req->method);
-    dbus_pending_call_cancel(call);
-    dbus_pending_call_unref(call);
-    free(req);
-}
-
-static dbus_bool_t dbus_func_args_async_valist(JNIEnv *env,
-                                        DBusConnection *conn,
-                                        int timeout_ms,
-                                        void (*user_cb)(DBusMessage *,
-                                                        void *,
-                                                        void*),
-                                        void *user,
-                                        void *nat,
-                                        const char *path,
-                                        const char *ifc,
-                                        const char *func,
-                                        int first_arg_type,
-                                        va_list args) {
-    DBusMessage *msg = NULL;
-    const char *name;
-    dbus_async_call_t *pending;
-    dbus_bool_t reply = FALSE;
-
-    /* Compose the command */
-    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
-
-    if (msg == NULL) {
-        ALOGE("Could not allocate D-Bus message object!");
-        goto done;
-    }
-
-    /* append arguments */
-    if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
-        ALOGE("Could not append argument to method call!");
-        goto done;
-    }
-
-    /* Make the call. */
-    pending = (dbus_async_call_t *)malloc(sizeof(dbus_async_call_t));
-    if (pending) {
-        DBusPendingCall *call;
-
-        pending->env = env;
-        pending->user_cb = user_cb;
-        pending->user = user;
-        pending->nat = nat;
-        //pending->method = msg;
-
-        reply = dbus_connection_send_with_reply(conn, msg,
-                                                &call,
-                                                timeout_ms);
-        if (reply == TRUE) {
-            dbus_pending_call_set_notify(call,
-                                         dbus_func_args_async_callback,
-                                         pending,
-                                         NULL);
-        }
-    }
-
-done:
-    if (msg) dbus_message_unref(msg);
-    return reply;
-}
-
-dbus_bool_t dbus_func_args_async(JNIEnv *env,
-                                 DBusConnection *conn,
-                                 int timeout_ms,
-                                 void (*reply)(DBusMessage *, void *, void*),
-                                 void *user,
-                                 void *nat,
-                                 const char *path,
-                                 const char *ifc,
-                                 const char *func,
-                                 int first_arg_type,
-                                 ...) {
-    dbus_bool_t ret;
-    va_list lst;
-    va_start(lst, first_arg_type);
-
-    ret = dbus_func_args_async_valist(env, conn,
-                                      timeout_ms,
-                                      reply, user, nat,
-                                      path, ifc, func,
-                                      first_arg_type, lst);
-    va_end(lst);
-    return ret;
-}
-
-// If err is NULL, then any errors will be ALOGE'd, and free'd and the reply
-// will be NULL.
-// If err is not NULL, then it is assumed that dbus_error_init was already
-// called, and error's will be returned to the caller without logging. The
-// return value is NULL iff an error was set. The client must free the error if
-// set.
-DBusMessage * dbus_func_args_timeout_valist(JNIEnv *env,
-                                            DBusConnection *conn,
-                                            int timeout_ms,
-                                            DBusError *err,
-                                            const char *path,
-                                            const char *ifc,
-                                            const char *func,
-                                            int first_arg_type,
-                                            va_list args) {
-
-    DBusMessage *msg = NULL, *reply = NULL;
-    const char *name;
-    bool return_error = (err != NULL);
-
-    if (!return_error) {
-        err = (DBusError*)malloc(sizeof(DBusError));
-        dbus_error_init(err);
-    }
-
-    /* Compose the command */
-    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, path, ifc, func);
-
-    if (msg == NULL) {
-        ALOGE("Could not allocate D-Bus message object!");
-        goto done;
-    }
-
-    /* append arguments */
-    if (!dbus_message_append_args_valist(msg, first_arg_type, args)) {
-        ALOGE("Could not append argument to method call!");
-        goto done;
-    }
-
-    /* Make the call. */
-    reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout_ms, err);
-    if (!return_error && dbus_error_is_set(err)) {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
-    }
-
-done:
-    if (!return_error) {
-        free(err);
-    }
-    if (msg) dbus_message_unref(msg);
-    return reply;
-}
-
-DBusMessage * dbus_func_args_timeout(JNIEnv *env,
-                                     DBusConnection *conn,
-                                     int timeout_ms,
-                                     const char *path,
-                                     const char *ifc,
-                                     const char *func,
-                                     int first_arg_type,
-                                     ...) {
-    DBusMessage *ret;
-    va_list lst;
-    va_start(lst, first_arg_type);
-    ret = dbus_func_args_timeout_valist(env, conn, timeout_ms, NULL,
-                                        path, ifc, func,
-                                        first_arg_type, lst);
-    va_end(lst);
-    return ret;
-}
-
-DBusMessage * dbus_func_args(JNIEnv *env,
-                             DBusConnection *conn,
-                             const char *path,
-                             const char *ifc,
-                             const char *func,
-                             int first_arg_type,
-                             ...) {
-    DBusMessage *ret;
-    va_list lst;
-    va_start(lst, first_arg_type);
-    ret = dbus_func_args_timeout_valist(env, conn, -1, NULL,
-                                        path, ifc, func,
-                                        first_arg_type, lst);
-    va_end(lst);
-    return ret;
-}
-
-DBusMessage * dbus_func_args_error(JNIEnv *env,
-                                   DBusConnection *conn,
-                                   DBusError *err,
-                                   const char *path,
-                                   const char *ifc,
-                                   const char *func,
-                                   int first_arg_type,
-                                   ...) {
-    DBusMessage *ret;
-    va_list lst;
-    va_start(lst, first_arg_type);
-    ret = dbus_func_args_timeout_valist(env, conn, -1, err,
-                                        path, ifc, func,
-                                        first_arg_type, lst);
-    va_end(lst);
-    return ret;
-}
-
-jint dbus_returns_unixfd(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    jint ret = -1;
-
-    dbus_error_init(&err);
-    if (!dbus_message_get_args(reply, &err,
-                               DBUS_TYPE_UNIX_FD, &ret,
-                               DBUS_TYPE_INVALID)) {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-    dbus_message_unref(reply);
-    return ret;
-}
-
-
-jint dbus_returns_int32(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    jint ret = -1;
-
-    dbus_error_init(&err);
-    if (!dbus_message_get_args(reply, &err,
-                               DBUS_TYPE_INT32, &ret,
-                               DBUS_TYPE_INVALID)) {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-    dbus_message_unref(reply);
-    return ret;
-}
-
-jint dbus_returns_uint32(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    jint ret = -1;
-
-    dbus_error_init(&err);
-    if (!dbus_message_get_args(reply, &err,
-                               DBUS_TYPE_UINT32, &ret,
-                               DBUS_TYPE_INVALID)) {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-    dbus_message_unref(reply);
-    return ret;
-}
-
-jstring dbus_returns_string(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    jstring ret = NULL;
-    const char *name;
-
-    dbus_error_init(&err);
-    if (dbus_message_get_args(reply, &err,
-                               DBUS_TYPE_STRING, &name,
-                               DBUS_TYPE_INVALID)) {
-        ret = env->NewStringUTF(name);
-    } else {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-    dbus_message_unref(reply);
-
-    return ret;
-}
-
-jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply) {
-    DBusError err;
-    jboolean ret = JNI_FALSE;
-    dbus_bool_t val = FALSE;
-
-    dbus_error_init(&err);
-
-    /* Check the return value. */
-    if (dbus_message_get_args(reply, &err,
-                               DBUS_TYPE_BOOLEAN, &val,
-                               DBUS_TYPE_INVALID)) {
-        ret = val == TRUE ? JNI_TRUE : JNI_FALSE;
-    } else {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-
-    dbus_message_unref(reply);
-    return ret;
-}
-
-static void set_object_array_element(JNIEnv *env, jobjectArray strArray,
-                                     const char *value, int index) {
-    jstring obj;
-    obj = env->NewStringUTF(value);
-    env->SetObjectArrayElement(strArray, index, obj);
-    env->DeleteLocalRef(obj);
-}
-
-jobjectArray dbus_returns_array_of_object_path(JNIEnv *env,
-                                               DBusMessage *reply) {
-
-    DBusError err;
-    char **list;
-    int i, len;
-    jobjectArray strArray = NULL;
-
-    dbus_error_init(&err);
-    if (dbus_message_get_args (reply,
-                               &err,
-                               DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
-                               &list, &len,
-                               DBUS_TYPE_INVALID)) {
-        jclass stringClass;
-        jstring classNameStr;
-
-        stringClass = env->FindClass("java/lang/String");
-        strArray = env->NewObjectArray(len, stringClass, NULL);
-
-        for (i = 0; i < len; i++)
-            set_object_array_element(env, strArray, list[i], i);
-    } else {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-
-    dbus_message_unref(reply);
-    return strArray;
-}
-
-jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    char **list;
-    int i, len;
-    jobjectArray strArray = NULL;
-
-    dbus_error_init(&err);
-    if (dbus_message_get_args (reply,
-                               &err,
-                               DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
-                               &list, &len,
-                               DBUS_TYPE_INVALID)) {
-        jclass stringClass;
-        jstring classNameStr;
-
-        //ALOGV("%s: there are %d elements in string array!", __FUNCTION__, len);
-
-        stringClass = env->FindClass("java/lang/String");
-        strArray = env->NewObjectArray(len, stringClass, NULL);
-
-        for (i = 0; i < len; i++)
-            set_object_array_element(env, strArray, list[i], i);
-    } else {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-
-    dbus_message_unref(reply);
-    return strArray;
-}
-
-jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply) {
-
-    DBusError err;
-    int i, len;
-    jbyte *list;
-    jbyteArray byteArray = NULL;
-
-    dbus_error_init(&err);
-    if (dbus_message_get_args(reply, &err,
-                              DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &list, &len,
-                              DBUS_TYPE_INVALID)) {
-        //ALOGV("%s: there are %d elements in byte array!", __FUNCTION__, len);
-        byteArray = env->NewByteArray(len);
-        if (byteArray)
-            env->SetByteArrayRegion(byteArray, 0, len, list);
-
-    } else {
-        LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-    }
-
-    dbus_message_unref(reply);
-    return byteArray;
-}
-
-void append_variant(DBusMessageIter *iter, int type, void *val)
-{
-    DBusMessageIter value_iter;
-    char var_type[2] = { type, '\0'};
-    dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, var_type, &value_iter);
-    dbus_message_iter_append_basic(&value_iter, type, val);
-    dbus_message_iter_close_container(iter, &value_iter);
-}
-
-static void dict_append_entry(DBusMessageIter *dict,
-                        const char *key, int type, void *val)
-{
-        DBusMessageIter dict_entry;
-        dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
-                                                        NULL, &dict_entry);
-
-        dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
-        append_variant(&dict_entry, type, val);
-        dbus_message_iter_close_container(dict, &dict_entry);
-}
-
-static void append_dict_valist(DBusMessageIter *iterator, const char *first_key,
-                                va_list var_args)
-{
-        DBusMessageIter dict;
-        int val_type;
-        const char *val_key;
-        void *val;
-
-        dbus_message_iter_open_container(iterator, DBUS_TYPE_ARRAY,
-                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-        val_key = first_key;
-        while (val_key) {
-                val_type = va_arg(var_args, int);
-                val = va_arg(var_args, void *);
-                dict_append_entry(&dict, val_key, val_type, val);
-                val_key = va_arg(var_args, char *);
-        }
-
-        dbus_message_iter_close_container(iterator, &dict);
-}
-
-void append_dict_args(DBusMessage *reply, const char *first_key, ...)
-{
-        DBusMessageIter iter;
-        va_list var_args;
-
-        dbus_message_iter_init_append(reply, &iter);
-
-        va_start(var_args, first_key);
-        append_dict_valist(&iter, first_key, var_args);
-        va_end(var_args);
-}
-
-
-int get_property(DBusMessageIter iter, Properties *properties,
-                  int max_num_properties, int *prop_index, property_value *value, int *len) {
-    DBusMessageIter prop_val, array_val_iter;
-    char *property = NULL;
-    uint32_t array_type;
-    char *str_val;
-    int i, j, type, int_val;
-
-    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
-        return -1;
-    dbus_message_iter_get_basic(&iter, &property);
-    if (!dbus_message_iter_next(&iter))
-        return -1;
-    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
-        return -1;
-    for (i = 0; i <  max_num_properties; i++) {
-        if (!strncmp(property, properties[i].name, strlen(property)))
-            break;
-    }
-    *prop_index = i;
-    if (i == max_num_properties)
-        return -1;
-
-    dbus_message_iter_recurse(&iter, &prop_val);
-    type = properties[*prop_index].type;
-    if (dbus_message_iter_get_arg_type(&prop_val) != type) {
-        ALOGE("Property type mismatch in get_property: %d, expected:%d, index:%d",
-             dbus_message_iter_get_arg_type(&prop_val), type, *prop_index);
-        return -1;
-    }
-
-    switch(type) {
-    case DBUS_TYPE_STRING:
-    case DBUS_TYPE_OBJECT_PATH:
-        dbus_message_iter_get_basic(&prop_val, &value->str_val);
-        *len = 1;
-        break;
-    case DBUS_TYPE_UINT32:
-    case DBUS_TYPE_INT16:
-    case DBUS_TYPE_BOOLEAN:
-        dbus_message_iter_get_basic(&prop_val, &int_val);
-        value->int_val = int_val;
-        *len = 1;
-        break;
-    case DBUS_TYPE_ARRAY:
-        dbus_message_iter_recurse(&prop_val, &array_val_iter);
-        array_type = dbus_message_iter_get_arg_type(&array_val_iter);
-        *len = 0;
-        value->array_val = NULL;
-        if (array_type == DBUS_TYPE_OBJECT_PATH ||
-            array_type == DBUS_TYPE_STRING){
-            j = 0;
-            do {
-               j ++;
-            } while(dbus_message_iter_next(&array_val_iter));
-            dbus_message_iter_recurse(&prop_val, &array_val_iter);
-            // Allocate  an array of char *
-            *len = j;
-            char **tmp = (char **)malloc(sizeof(char *) * *len);
-            if (!tmp)
-                return -1;
-            j = 0;
-            do {
-               dbus_message_iter_get_basic(&array_val_iter, &tmp[j]);
-               j ++;
-            } while(dbus_message_iter_next(&array_val_iter));
-            value->array_val = tmp;
-        }
-        break;
-    default:
-        return -1;
-    }
-    return 0;
-}
-
-void create_prop_array(JNIEnv *env, jobjectArray strArray, Properties *property,
-                       property_value *value, int len, int *array_index ) {
-    char **prop_val = NULL;
-    char buf[32] = {'\0'}, buf1[32] = {'\0'};
-    int i;
-
-    char *name = property->name;
-    int prop_type = property->type;
-
-    set_object_array_element(env, strArray, name, *array_index);
-    *array_index += 1;
-
-    if (prop_type == DBUS_TYPE_UINT32 || prop_type == DBUS_TYPE_INT16) {
-        sprintf(buf, "%d", value->int_val);
-        set_object_array_element(env, strArray, buf, *array_index);
-        *array_index += 1;
-    } else if (prop_type == DBUS_TYPE_BOOLEAN) {
-        sprintf(buf, "%s", value->int_val ? "true" : "false");
-
-        set_object_array_element(env, strArray, buf, *array_index);
-        *array_index += 1;
-    } else if (prop_type == DBUS_TYPE_ARRAY) {
-        // Write the length first
-        sprintf(buf1, "%d", len);
-        set_object_array_element(env, strArray, buf1, *array_index);
-        *array_index += 1;
-
-        prop_val = value->array_val;
-        for (i = 0; i < len; i++) {
-            set_object_array_element(env, strArray, prop_val[i], *array_index);
-            *array_index += 1;
-        }
-    } else {
-        set_object_array_element(env, strArray, (const char *) value->str_val, *array_index);
-        *array_index += 1;
-    }
-}
-
-jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
-                              const int max_num_properties) {
-    DBusMessageIter dict_entry, dict;
-    jobjectArray strArray = NULL;
-    property_value value;
-    int i, size = 0,array_index = 0;
-    int len = 0, prop_type = DBUS_TYPE_INVALID, prop_index = -1, type;
-    struct {
-        property_value value;
-        int len;
-        bool used;
-    } values[max_num_properties];
-    int t, j;
-
-    jclass stringClass = env->FindClass("java/lang/String");
-    DBusError err;
-    dbus_error_init(&err);
-
-    for (i = 0; i < max_num_properties; i++) {
-        values[i].used = false;
-    }
-
-    if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
-        goto failure;
-    dbus_message_iter_recurse(iter, &dict);
-    do {
-        len = 0;
-        if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
-            goto failure;
-        dbus_message_iter_recurse(&dict, &dict_entry);
-
-        if (!get_property(dict_entry, properties, max_num_properties, &prop_index,
-                          &value, &len)) {
-            size += 2;
-            if (properties[prop_index].type == DBUS_TYPE_ARRAY)
-                size += len;
-            values[prop_index].value = value;
-            values[prop_index].len = len;
-            values[prop_index].used = true;
-        } else {
-            goto failure;
-        }
-    } while(dbus_message_iter_next(&dict));
-
-    strArray = env->NewObjectArray(size, stringClass, NULL);
-
-    for (i = 0; i < max_num_properties; i++) {
-        if (values[i].used) {
-            create_prop_array(env, strArray, &properties[i], &values[i].value, values[i].len,
-                              &array_index);
-
-            if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used
-                   && values[i].value.array_val != NULL)
-                free(values[i].value.array_val);
-        }
-
-    }
-    return strArray;
-
-failure:
-    if (dbus_error_is_set(&err))
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    for (i = 0; i < max_num_properties; i++)
-        if (properties[i].type == DBUS_TYPE_ARRAY && values[i].used == true
-                                        && values[i].value.array_val != NULL)
-            free(values[i].value.array_val);
-    return NULL;
-}
-
-jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
-                           Properties *properties, int max_num_properties) {
-    DBusMessageIter iter;
-    DBusError err;
-    jobjectArray strArray = NULL;
-    jclass stringClass= env->FindClass("java/lang/String");
-    int len = 0, prop_index = -1;
-    int array_index = 0, size = 0;
-    property_value value;
-
-    dbus_error_init(&err);
-    if (!dbus_message_iter_init(msg, &iter))
-        goto failure;
-
-    if (!get_property(iter, properties, max_num_properties,
-                      &prop_index, &value, &len)) {
-        size += 2;
-        if (properties[prop_index].type == DBUS_TYPE_ARRAY)
-            size += len;
-        strArray = env->NewObjectArray(size, stringClass, NULL);
-
-        create_prop_array(env, strArray, &properties[prop_index],
-                          &value, len, &array_index);
-
-        if (properties[prop_index].type == DBUS_TYPE_ARRAY && value.array_val != NULL)
-             free(value.array_val);
-
-        return strArray;
-    }
-failure:
-    LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-    return NULL;
-}
-
-jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg) {
-    return parse_property_change(env, msg, (Properties *) &adapter_properties,
-                    sizeof(adapter_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg) {
-    return parse_property_change(env, msg, (Properties *) &remote_device_properties,
-                    sizeof(remote_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_input_property_change(JNIEnv *env, DBusMessage *msg) {
-    return parse_property_change(env, msg, (Properties *) &input_properties,
-                    sizeof(input_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_pan_property_change(JNIEnv *env, DBusMessage *msg) {
-    return parse_property_change(env, msg, (Properties *) &pan_properties,
-                    sizeof(pan_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter) {
-    return parse_properties(env, iter, (Properties *) &adapter_properties,
-                            sizeof(adapter_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter) {
-    return parse_properties(env, iter, (Properties *) &remote_device_properties,
-                          sizeof(remote_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_input_properties(JNIEnv *env, DBusMessageIter *iter) {
-    return parse_properties(env, iter, (Properties *) &input_properties,
-                          sizeof(input_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_device_properties(JNIEnv *env, DBusMessageIter *iter) {
-    return parse_properties(env, iter, (Properties *) &health_device_properties,
-                          sizeof(health_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_device_property_change(JNIEnv *env, DBusMessage *msg) {
-    return parse_property_change(env, msg, (Properties *) &health_device_properties,
-                    sizeof(health_device_properties) / sizeof(Properties));
-}
-
-jobjectArray parse_health_channel_properties(JNIEnv *env, DBusMessageIter *iter) {
-    return parse_properties(env, iter, (Properties *) &health_channel_properties,
-                          sizeof(health_channel_properties) / sizeof(Properties));
-}
-
-int get_bdaddr(const char *str, bdaddr_t *ba) {
-    char *d = ((char *)ba) + 5, *endp;
-    int i;
-    for(i = 0; i < 6; i++) {
-        *d-- = strtol(str, &endp, 16);
-        if (*endp != ':' && i != 5) {
-            memset(ba, 0, sizeof(bdaddr_t));
-            return -1;
-        }
-        str = endp + 1;
-    }
-    return 0;
-}
-
-void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
-    const uint8_t *b = (const uint8_t *)ba;
-    sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-            b[5], b[4], b[3], b[2], b[1], b[0]);
-}
-
-bool debug_no_encrypt() {
-    return false;
-#if 0
-    char value[PROPERTY_VALUE_MAX] = "";
-
-    property_get("debug.bt.no_encrypt", value, "");
-    if (!strncmp("true", value, PROPERTY_VALUE_MAX) ||
-        !strncmp("1", value, PROPERTY_VALUE_MAX)) {
-        ALOGD("mandatory bluetooth encryption disabled");
-        return true;
-    } else {
-        return false;
-    }
-#endif
-}
-#endif
-
-} /* namespace android */
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
deleted file mode 100644
index daf4bb2..0000000
--- a/core/jni/android_bluetooth_common.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_BLUETOOTH_COMMON_H
-#define ANDROID_BLUETOOTH_COMMON_H
-
-// Set to 0 to enable verbose bluetooth logging
-#define LOG_NDEBUG 1
-
-#include "jni.h"
-#include "utils/Log.h"
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/poll.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#include <bluetooth/bluetooth.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-#define BLUEZ_DBUS_BASE_PATH      "/org/bluez"
-#define BLUEZ_DBUS_BASE_IFC       "org.bluez"
-#define BLUEZ_ERROR_IFC           "org.bluez.Error"
-
-// It would be nicer to retrieve this from bluez using GetDefaultAdapter,
-// but this is only possible when the adapter is up (and hcid is running).
-// It is much easier just to hardcode bluetooth adapter to hci0
-#define BLUETOOTH_ADAPTER_HCI_NUM 0
-#define BLUEZ_ADAPTER_OBJECT_NAME BLUEZ_DBUS_BASE_PATH "/hci0"
-
-#define BTADDR_SIZE 18   // size of BT address character array (including null)
-
-// size of the dbus event loops pollfd structure, hopefully never to be grown
-#define DEFAULT_INITIAL_POLLFD_COUNT 8
-
-jfieldID get_field(JNIEnv *env,
-                   jclass clazz,
-                   const char *member,
-                   const char *mtype);
-
-// ALOGE and free a D-Bus error
-// Using #define so that __FUNCTION__ resolves usefully
-#define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) \
-    {   ALOGE("%s: D-Bus error in %s: %s (%s)", __FUNCTION__, \
-        dbus_message_get_member((msg)), (err)->name, (err)->message); \
-         dbus_error_free((err)); }
-#define LOG_AND_FREE_DBUS_ERROR(err) \
-    {   ALOGE("%s: D-Bus error: %s (%s)", __FUNCTION__, \
-        (err)->name, (err)->message); \
-        dbus_error_free((err)); }
-
-struct event_loop_native_data_t {
-    DBusConnection *conn;
-    const char *adapter;
-
-    /* protects the thread */
-    pthread_mutex_t thread_mutex;
-    pthread_t thread;
-    /* our comms socket */
-    /* mem for the list of sockets to listen to */
-    struct pollfd *pollData;
-    int pollMemberCount;
-    int pollDataSize;
-    /* mem for matching set of dbus watch ptrs */
-    DBusWatch **watchData;
-    /* pair of sockets for event loop control, Reader and Writer */
-    int controlFdR;
-    int controlFdW;
-    /* our vm and env Version for future env generation */
-    JavaVM *vm;
-    int envVer;
-    /* reference to our java self */
-    jobject me;
-    /* flag to indicate if the event loop thread is running */
-    bool running;
-};
-
-struct _Properties {
-    char name[32];
-    int type;
-};
-typedef struct _Properties Properties;
-
-dbus_bool_t dbus_func_args_async(JNIEnv *env,
-                                 DBusConnection *conn,
-                                 int timeout_ms,
-                                 void (*reply)(DBusMessage *, void *, void *),
-                                 void *user,
-                                 void *nat,
-                                 const char *path,
-                                 const char *ifc,
-                                 const char *func,
-                                 int first_arg_type,
-                                 ...);
-
-DBusMessage * dbus_func_args(JNIEnv *env,
-                             DBusConnection *conn,
-                             const char *path,
-                             const char *ifc,
-                             const char *func,
-                             int first_arg_type,
-                             ...);
-
-DBusMessage * dbus_func_args_error(JNIEnv *env,
-                                   DBusConnection *conn,
-                                   DBusError *err,
-                                   const char *path,
-                                   const char *ifc,
-                                   const char *func,
-                                   int first_arg_type,
-                                   ...);
-
-DBusMessage * dbus_func_args_timeout(JNIEnv *env,
-                                     DBusConnection *conn,
-                                     int timeout_ms,
-                                     const char *path,
-                                     const char *ifc,
-                                     const char *func,
-                                     int first_arg_type,
-                                     ...);
-
-DBusMessage * dbus_func_args_timeout_valist(JNIEnv *env,
-                                            DBusConnection *conn,
-                                            int timeout_ms,
-                                            DBusError *err,
-                                            const char *path,
-                                            const char *ifc,
-                                            const char *func,
-                                            int first_arg_type,
-                                            va_list args);
-
-jint dbus_returns_int32(JNIEnv *env, DBusMessage *reply);
-jint dbus_returns_uint32(JNIEnv *env, DBusMessage *reply);
-jint dbus_returns_unixfd(JNIEnv *env, DBusMessage *reply);
-jstring dbus_returns_string(JNIEnv *env, DBusMessage *reply);
-jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply);
-jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply);
-jobjectArray dbus_returns_array_of_object_path(JNIEnv *env, DBusMessage *reply);
-jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply);
-
-jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
-                              const int max_num_properties);
-jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
-                                   Properties *properties, int max_num_properties);
-jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_input_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_health_device_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_health_channel_properties(JNIEnv *env, DBusMessageIter *iter);
-jobjectArray parse_input_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_pan_property_change(JNIEnv *env, DBusMessage *msg);
-jobjectArray parse_health_device_property_change(JNIEnv *env, DBusMessage *msg);
-
-void append_dict_args(DBusMessage *reply, const char *first_key, ...);
-void append_variant(DBusMessageIter *iter, int type, void *val);
-int get_bdaddr(const char *str, bdaddr_t *ba);
-void get_bdaddr_as_string(const bdaddr_t *ba, char *str);
-
-bool debug_no_encrypt();
-
-
-// Result codes from Bluez DBus calls
-#define BOND_RESULT_ERROR                      -1
-#define BOND_RESULT_SUCCESS                     0
-#define BOND_RESULT_AUTH_FAILED                 1
-#define BOND_RESULT_AUTH_REJECTED               2
-#define BOND_RESULT_AUTH_CANCELED               3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN          4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS       5
-#define BOND_RESULT_AUTH_TIMEOUT                6
-#define BOND_RESULT_REPEATED_ATTEMPTS           7
-
-#define PAN_DISCONNECT_FAILED_NOT_CONNECTED  1000
-#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
-#define PAN_CONNECT_FAILED_ATTEMPT_FAILED    1002
-#define PAN_OPERATION_GENERIC_FAILURE        1003
-#define PAN_OPERATION_SUCCESS                1004
-
-#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED  5000
-#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
-#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED    5002
-#define INPUT_OPERATION_GENERIC_FAILURE        5003
-#define INPUT_OPERATION_SUCCESS                5004
-
-#define HEALTH_OPERATION_SUCCESS               6000
-#define HEALTH_OPERATION_ERROR                 6001
-#define HEALTH_OPERATION_INVALID_ARGS          6002
-#define HEALTH_OPERATION_GENERIC_FAILURE       6003
-#define HEALTH_OPERATION_NOT_FOUND             6004
-#define HEALTH_OPERATION_NOT_ALLOWED           6005
-
-#endif
-} /* namespace android */
-
-#endif/*ANDROID_BLUETOOTH_COMMON_H*/
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
deleted file mode 100644
index d065a9e..0000000
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothA2dpService.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#ifdef HAVE_BLUETOOTH
-static jmethodID method_onSinkPropertyChanged;
-static jmethodID method_onConnectSinkResult;
-
-typedef struct {
-    JavaVM *vm;
-    int envVer;
-    DBusConnection *conn;
-    jobject me;  // for callbacks to java
-} native_data_t;
-
-static native_data_t *nat = NULL;  // global native data
-static void onConnectSinkResult(DBusMessage *msg, void *user, void *n);
-
-static Properties sink_properties[] = {
-        {"State", DBUS_TYPE_STRING},
-        {"Connected", DBUS_TYPE_BOOLEAN},
-        {"Playing", DBUS_TYPE_BOOLEAN},
-      };
-#endif
-
-/* Returns true on success (even if adapter is present but disabled).
- * Return false if dbus is down, or another serious error (out of memory)
-*/
-static bool initNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    nat = (native_data_t *)calloc(1, sizeof(native_data_t));
-    if (NULL == nat) {
-        ALOGE("%s: out of memory!", __FUNCTION__);
-        return false;
-    }
-    env->GetJavaVM( &(nat->vm) );
-    nat->envVer = env->GetVersion();
-    nat->me = env->NewGlobalRef(object);
-
-    DBusError err;
-    dbus_error_init(&err);
-    dbus_threads_init_default();
-    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-    if (dbus_error_is_set(&err)) {
-        ALOGE("Could not get onto the system bus: %s", err.message);
-        dbus_error_free(&err);
-        return false;
-    }
-    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
-#endif  /*HAVE_BLUETOOTH*/
-    return true;
-}
-
-static void cleanupNative(JNIEnv* env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        dbus_connection_close(nat->conn);
-        env->DeleteGlobalRef(nat->me);
-        free(nat);
-        nat = NULL;
-    }
-#endif
-}
-
-static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
-                                            jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        reply = dbus_func_args_timeout(env,
-                                   nat->conn, -1, c_path,
-                                   "org.bluez.AudioSink", "GetProperties",
-                                   DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        if (!reply && dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
-            return NULL;
-        } else if (!reply) {
-            ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return NULL;
-        }
-        DBusMessageIter iter;
-        if (dbus_message_iter_init(reply, &iter))
-            return parse_properties(env, &iter, (Properties *)&sink_properties,
-                                 sizeof(sink_properties) / sizeof(Properties));
-    }
-#endif
-    return NULL;
-}
-
-
-static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1, onConnectSinkResult, context_path,
-                                    nat, c_path, "org.bluez.AudioSink", "Connect",
-                                    DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
-                                    c_path, "org.bluez.AudioSink", "Disconnect",
-                                    DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean suspendSinkNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
-                           c_path, "org.bluez.audio.Sink", "Suspend",
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean resumeSinkNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
-                           c_path, "org.bluez.audio.Sink", "Resume",
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
-                           c_path, "org.bluez.Control", "VolumeUp",
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean avrcpVolumeDownNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
-                           c_path, "org.bluez.Control", "VolumeDown",
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-#ifdef HAVE_BLUETOOTH
-DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
-    DBusError err;
-
-    if (!nat) {
-        ALOGV("... skipping %s\n", __FUNCTION__);
-        ALOGV("... ignored\n");
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    dbus_error_init(&err);
-
-    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    if (dbus_message_is_signal(msg, "org.bluez.AudioSink",
-                                      "PropertyChanged")) {
-        jobjectArray str_array =
-                    parse_property_change(env, msg, (Properties *)&sink_properties,
-                                sizeof(sink_properties) / sizeof(Properties));
-        const char *c_path = dbus_message_get_path(msg);
-        jstring path = env->NewStringUTF(c_path);
-        env->CallVoidMethod(nat->me,
-                            method_onSinkPropertyChanged,
-                            path,
-                            str_array);
-        env->DeleteLocalRef(path);
-        result = DBUS_HANDLER_RESULT_HANDLED;
-        return result;
-    } else {
-        ALOGV("... ignored");
-    }
-    if (env->ExceptionCheck()) {
-        ALOGE("VM Exception occurred while handling %s.%s (%s) in %s,"
-             " leaving for VM",
-             dbus_message_get_interface(msg), dbus_message_get_member(msg),
-             dbus_message_get_path(msg), __FUNCTION__);
-    }
-
-    return result;
-}
-
-void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *path = (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-
-    bool result = JNI_TRUE;
-    if (dbus_set_error_from_message(&err, msg)) {
-        LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
-    }
-    ALOGV("... Device Path = %s, result = %d", path, result);
-
-    jstring jPath = env->NewStringUTF(path);
-    env->CallVoidMethod(nat->me,
-                        method_onConnectSinkResult,
-                        jPath,
-                        result);
-    env->DeleteLocalRef(jPath);
-    free(user);
-}
-
-
-#endif
-
-
-static JNINativeMethod sMethods[] = {
-    {"initNative", "()Z", (void *)initNative},
-    {"cleanupNative", "()V", (void *)cleanupNative},
-
-    /* Bluez audio 4.47 API */
-    {"connectSinkNative", "(Ljava/lang/String;)Z", (void *)connectSinkNative},
-    {"disconnectSinkNative", "(Ljava/lang/String;)Z", (void *)disconnectSinkNative},
-    {"suspendSinkNative", "(Ljava/lang/String;)Z", (void*)suspendSinkNative},
-    {"resumeSinkNative", "(Ljava/lang/String;)Z", (void*)resumeSinkNative},
-    {"getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
-                                    (void *)getSinkPropertiesNative},
-    {"avrcpVolumeUpNative", "(Ljava/lang/String;)Z", (void*)avrcpVolumeUpNative},
-    {"avrcpVolumeDownNative", "(Ljava/lang/String;)Z", (void*)avrcpVolumeDownNative},
-};
-
-int register_android_server_BluetoothA2dpService(JNIEnv *env) {
-    jclass clazz = env->FindClass("android/server/BluetoothA2dpService");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/server/BluetoothA2dpService");
-        return -1;
-    }
-
-#ifdef HAVE_BLUETOOTH
-    method_onSinkPropertyChanged = env->GetMethodID(clazz, "onSinkPropertyChanged",
-                                          "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onConnectSinkResult = env->GetMethodID(clazz, "onConnectSinkResult",
-                                                         "(Ljava/lang/String;Z)V");
-#endif
-
-    return AndroidRuntime::registerNativeMethods(env,
-                "android/server/BluetoothA2dpService", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
deleted file mode 100644
index 8a69ba4..0000000
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ /dev/null
@@ -1,1585 +0,0 @@
-/*
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "BluetoothEventLoop.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "cutils/sockets.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#endif
-
-namespace android {
-
-#define CREATE_DEVICE_ALREADY_EXISTS 1
-#define CREATE_DEVICE_SUCCESS 0
-#define CREATE_DEVICE_FAILED -1
-
-#ifdef HAVE_BLUETOOTH
-static jfieldID field_mNativeData;
-
-static jmethodID method_onPropertyChanged;
-static jmethodID method_onDevicePropertyChanged;
-static jmethodID method_onDeviceFound;
-static jmethodID method_onDeviceDisappeared;
-static jmethodID method_onDeviceCreated;
-static jmethodID method_onDeviceRemoved;
-static jmethodID method_onDeviceDisconnectRequested;
-static jmethodID method_onNetworkDeviceDisconnected;
-static jmethodID method_onNetworkDeviceConnected;
-
-static jmethodID method_onCreatePairedDeviceResult;
-static jmethodID method_onCreateDeviceResult;
-static jmethodID method_onDiscoverServicesResult;
-static jmethodID method_onGetDeviceServiceChannelResult;
-
-static jmethodID method_onRequestPinCode;
-static jmethodID method_onRequestPasskey;
-static jmethodID method_onRequestPasskeyConfirmation;
-static jmethodID method_onRequestPairingConsent;
-static jmethodID method_onDisplayPasskey;
-static jmethodID method_onRequestOobData;
-static jmethodID method_onAgentOutOfBandDataAvailable;
-static jmethodID method_onAgentAuthorize;
-static jmethodID method_onAgentCancel;
-
-static jmethodID method_onInputDevicePropertyChanged;
-static jmethodID method_onInputDeviceConnectionResult;
-static jmethodID method_onPanDevicePropertyChanged;
-static jmethodID method_onPanDeviceConnectionResult;
-static jmethodID method_onHealthDevicePropertyChanged;
-static jmethodID method_onHealthDeviceChannelChanged;
-static jmethodID method_onHealthDeviceConnectionResult;
-
-typedef event_loop_native_data_t native_data_t;
-
-#define EVENT_LOOP_REFS 10
-
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
-    return (native_data_t *)(env->GetIntField(object,
-                                                 field_mNativeData));
-}
-
-native_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) {
-    return get_native_data(env, object);
-}
-
-#endif
-static void classInitNative(JNIEnv* env, jclass clazz) {
-    ALOGV("%s", __FUNCTION__);
-
-#ifdef HAVE_BLUETOOTH
-    method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
-                                                "([Ljava/lang/String;)V");
-    method_onDevicePropertyChanged = env->GetMethodID(clazz,
-                                                      "onDevicePropertyChanged",
-                                                      "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound",
-                                            "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared",
-                                                  "(Ljava/lang/String;)V");
-    method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
-    method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
-    method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
-                                                        "(Ljava/lang/String;)V");
-    method_onNetworkDeviceConnected = env->GetMethodID(clazz, "onNetworkDeviceConnected",
-                                                     "(Ljava/lang/String;Ljava/lang/String;I)V");
-    method_onNetworkDeviceDisconnected = env->GetMethodID(clazz, "onNetworkDeviceDisconnected",
-                                                              "(Ljava/lang/String;)V");
-
-    method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
-                                                         "(Ljava/lang/String;I)V");
-    method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
-                                                         "(Ljava/lang/String;I)V");
-    method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
-                                                         "(Ljava/lang/String;Z)V");
-
-    method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
-                                               "(Ljava/lang/String;Ljava/lang/String;I)V");
-    method_onAgentOutOfBandDataAvailable = env->GetMethodID(clazz, "onAgentOutOfBandDataAvailable",
-                                               "(Ljava/lang/String;)Z");
-    method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V");
-    method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode",
-                                               "(Ljava/lang/String;I)V");
-    method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
-                                               "(Ljava/lang/String;I)V");
-    method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
-                                               "(Ljava/lang/String;II)V");
-    method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
-                                               "(Ljava/lang/String;I)V");
-    method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
-                                               "(Ljava/lang/String;II)V");
-    method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
-                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
-                                               "(Ljava/lang/String;I)V");
-    method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
-                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
-                                               "(Ljava/lang/String;I)V");
-    method_onHealthDeviceConnectionResult = env->GetMethodID(clazz,
-                                                             "onHealthDeviceConnectionResult",
-                                                             "(II)V");
-    method_onHealthDevicePropertyChanged = env->GetMethodID(clazz, "onHealthDevicePropertyChanged",
-                                               "(Ljava/lang/String;[Ljava/lang/String;)V");
-    method_onHealthDeviceChannelChanged = env->GetMethodID(clazz, "onHealthDeviceChannelChanged",
-                                               "(Ljava/lang/String;Ljava/lang/String;Z)V");
-    method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
-                                               "(Ljava/lang/String;I)V");
-
-    field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
-#endif
-}
-
-static void initializeNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
-    if (NULL == nat) {
-        ALOGE("%s: out of memory!", __FUNCTION__);
-        return;
-    }
-
-    pthread_mutex_init(&(nat->thread_mutex), NULL);
-
-    env->SetIntField(object, field_mNativeData, (jint)nat);
-
-    {
-        DBusError err;
-        dbus_error_init(&err);
-        dbus_threads_init_default();
-        nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-        if (dbus_error_is_set(&err)) {
-            ALOGE("%s: Could not get onto the system bus!", __FUNCTION__);
-            dbus_error_free(&err);
-        }
-        dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
-    }
-#endif
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat =
-            (native_data_t *)env->GetIntField(object, field_mNativeData);
-
-    pthread_mutex_destroy(&(nat->thread_mutex));
-
-    if (nat) {
-        free(nat);
-    }
-#endif
-}
-
-#ifdef HAVE_BLUETOOTH
-static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
-                                      void *data);
-DBusHandlerResult agent_event_filter(DBusConnection *conn,
-                                     DBusMessage *msg,
-                                     void *data);
-static int register_agent(native_data_t *nat,
-                          const char *agent_path, const char *capabilities);
-
-static const DBusObjectPathVTable agent_vtable = {
-    NULL, agent_event_filter, NULL, NULL, NULL, NULL
-};
-
-static unsigned int unix_events_to_dbus_flags(short events) {
-    return (events & DBUS_WATCH_READABLE ? POLLIN : 0) |
-           (events & DBUS_WATCH_WRITABLE ? POLLOUT : 0) |
-           (events & DBUS_WATCH_ERROR ? POLLERR : 0) |
-           (events & DBUS_WATCH_HANGUP ? POLLHUP : 0);
-}
-
-static short dbus_flags_to_unix_events(unsigned int flags) {
-    return (flags & POLLIN ? DBUS_WATCH_READABLE : 0) |
-           (flags & POLLOUT ? DBUS_WATCH_WRITABLE : 0) |
-           (flags & POLLERR ? DBUS_WATCH_ERROR : 0) |
-           (flags & POLLHUP ? DBUS_WATCH_HANGUP : 0);
-}
-
-static jboolean setUpEventLoop(native_data_t *nat) {
-    ALOGV("%s", __FUNCTION__);
-
-    if (nat != NULL && nat->conn != NULL) {
-        dbus_threads_init_default();
-        DBusError err;
-        dbus_error_init(&err);
-
-        const char *agent_path = "/android/bluetooth/agent";
-        const char *capabilities = "DisplayYesNo";
-        if (register_agent(nat, agent_path, capabilities) < 0) {
-            dbus_connection_unregister_object_path (nat->conn, agent_path);
-            return JNI_FALSE;
-        }
-
-        // Add a filter for all incoming messages
-        if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){
-            return JNI_FALSE;
-        }
-
-        // Set which messages will be processed by this dbus connection
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='org.freedesktop.DBus'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-
-        dbus_bus_add_match(nat->conn,
-                "type='signal',interface='org.bluez.AudioSink'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-            return JNI_FALSE;
-        }
-
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
-}
-
-
-const char * get_adapter_path(DBusConnection *conn) {
-    DBusMessage *msg = NULL, *reply = NULL;
-    DBusError err;
-    const char *device_path = NULL;
-    int attempt = 0;
-
-    for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
-        msg = dbus_message_new_method_call("org.bluez", "/",
-              "org.bluez.Manager", "DefaultAdapter");
-        if (!msg) {
-            ALOGE("%s: Can't allocate new method call for get_adapter_path!",
-                  __FUNCTION__);
-            return NULL;
-        }
-        dbus_message_append_args(msg, DBUS_TYPE_INVALID);
-        dbus_error_init(&err);
-        reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                if (dbus_error_has_name(&err,
-                    "org.freedesktop.DBus.Error.ServiceUnknown")) {
-                    // bluetoothd is still down, retry
-                    LOG_AND_FREE_DBUS_ERROR(&err);
-                    usleep(10000);  // 10 ms
-                    continue;
-                } else {
-                    // Some other error we weren't expecting
-                    LOG_AND_FREE_DBUS_ERROR(&err);
-                }
-            }
-            goto failed;
-        }
-    }
-    if (attempt == 1000) {
-        ALOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
-        goto failed;
-    }
-
-    if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
-                               &device_path, DBUS_TYPE_INVALID)
-                               || !device_path){
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        goto failed;
-    }
-    dbus_message_unref(msg);
-    return device_path;
-
-failed:
-    dbus_message_unref(msg);
-    return NULL;
-}
-
-static int register_agent(native_data_t *nat,
-                          const char * agent_path, const char * capabilities)
-{
-    DBusMessage *msg, *reply;
-    DBusError err;
-    dbus_bool_t oob = TRUE;
-
-    if (!dbus_connection_register_object_path(nat->conn, agent_path,
-            &agent_vtable, nat)) {
-        ALOGE("%s: Can't register object path %s for agent!",
-              __FUNCTION__, agent_path);
-        return -1;
-    }
-
-    nat->adapter = get_adapter_path(nat->conn);
-    if (nat->adapter == NULL) {
-        return -1;
-    }
-    msg = dbus_message_new_method_call("org.bluez", nat->adapter,
-          "org.bluez.Adapter", "RegisterAgent");
-    if (!msg) {
-        ALOGE("%s: Can't allocate new method call for agent!",
-              __FUNCTION__);
-        return -1;
-    }
-    dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
-                             DBUS_TYPE_STRING, &capabilities,
-                             DBUS_TYPE_INVALID);
-
-    dbus_error_init(&err);
-    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-    dbus_message_unref(msg);
-
-    if (!reply) {
-        ALOGE("%s: Can't register agent!", __FUNCTION__);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        return -1;
-    }
-
-    dbus_message_unref(reply);
-    dbus_connection_flush(nat->conn);
-
-    return 0;
-}
-
-static void tearDownEventLoop(native_data_t *nat) {
-    ALOGV("%s", __FUNCTION__);
-    if (nat != NULL && nat->conn != NULL) {
-
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-        const char * agent_path = "/android/bluetooth/agent";
-
-        msg = dbus_message_new_method_call("org.bluez",
-                                           nat->adapter,
-                                           "org.bluez.Adapter",
-                                           "UnregisterAgent");
-        if (msg != NULL) {
-            dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
-                                     DBUS_TYPE_INVALID);
-            reply = dbus_connection_send_with_reply_and_block(nat->conn,
-                                                              msg, -1, &err);
-
-            if (!reply) {
-                if (dbus_error_is_set(&err)) {
-                    LOG_AND_FREE_DBUS_ERROR(&err);
-                    dbus_error_free(&err);
-                }
-            } else {
-                dbus_message_unref(reply);
-            }
-            dbus_message_unref(msg);
-        } else {
-             ALOGE("%s: Can't create new method call!", __FUNCTION__);
-        }
-
-        dbus_connection_flush(nat->conn);
-        dbus_connection_unregister_object_path(nat->conn, agent_path);
-
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".AudioSink'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Input'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Network'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".NetworkServer'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".HealthDevice'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='org.bluez.audio.Manager'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-        dbus_bus_remove_match(nat->conn,
-                "type='signal',interface='org.freedesktop.DBus'",
-                &err);
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
-        }
-
-        dbus_connection_remove_filter(nat->conn, event_filter, nat);
-    }
-}
-
-
-#define EVENT_LOOP_EXIT 1
-#define EVENT_LOOP_ADD  2
-#define EVENT_LOOP_REMOVE 3
-#define EVENT_LOOP_WAKEUP 4
-
-dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
-    native_data_t *nat = (native_data_t *)data;
-
-    if (dbus_watch_get_enabled(watch)) {
-        // note that we can't just send the watch and inspect it later
-        // because we may get a removeWatch call before this data is reacted
-        // to by our eventloop and remove this watch..  reading the add first
-        // and then inspecting the recently deceased watch would be bad.
-        char control = EVENT_LOOP_ADD;
-        write(nat->controlFdW, &control, sizeof(char));
-
-        int fd = dbus_watch_get_fd(watch);
-        write(nat->controlFdW, &fd, sizeof(int));
-
-        unsigned int flags = dbus_watch_get_flags(watch);
-        write(nat->controlFdW, &flags, sizeof(unsigned int));
-
-        write(nat->controlFdW, &watch, sizeof(DBusWatch*));
-    }
-    return true;
-}
-
-void dbusRemoveWatch(DBusWatch *watch, void *data) {
-    native_data_t *nat = (native_data_t *)data;
-
-    char control = EVENT_LOOP_REMOVE;
-    write(nat->controlFdW, &control, sizeof(char));
-
-    int fd = dbus_watch_get_fd(watch);
-    write(nat->controlFdW, &fd, sizeof(int));
-
-    unsigned int flags = dbus_watch_get_flags(watch);
-    write(nat->controlFdW, &flags, sizeof(unsigned int));
-}
-
-void dbusToggleWatch(DBusWatch *watch, void *data) {
-    if (dbus_watch_get_enabled(watch)) {
-        dbusAddWatch(watch, data);
-    } else {
-        dbusRemoveWatch(watch, data);
-    }
-}
-
-void dbusWakeup(void *data) {
-    native_data_t *nat = (native_data_t *)data;
-
-    char control = EVENT_LOOP_WAKEUP;
-    write(nat->controlFdW, &control, sizeof(char));
-}
-
-static void handleWatchAdd(native_data_t *nat) {
-    DBusWatch *watch;
-    int newFD;
-    unsigned int flags;
-
-    read(nat->controlFdR, &newFD, sizeof(int));
-    read(nat->controlFdR, &flags, sizeof(unsigned int));
-    read(nat->controlFdR, &watch, sizeof(DBusWatch *));
-    short events = dbus_flags_to_unix_events(flags);
-
-    for (int y = 0; y<nat->pollMemberCount; y++) {
-        if ((nat->pollData[y].fd == newFD) &&
-                (nat->pollData[y].events == events)) {
-            ALOGV("DBusWatch duplicate add");
-            return;
-        }
-    }
-    if (nat->pollMemberCount == nat->pollDataSize) {
-        ALOGV("Bluetooth EventLoop poll struct growing");
-        struct pollfd *temp = (struct pollfd *)malloc(
-                sizeof(struct pollfd) * (nat->pollMemberCount+1));
-        if (!temp) {
-            return;
-        }
-        memcpy(temp, nat->pollData, sizeof(struct pollfd) *
-                nat->pollMemberCount);
-        free(nat->pollData);
-        nat->pollData = temp;
-        DBusWatch **temp2 = (DBusWatch **)malloc(sizeof(DBusWatch *) *
-                (nat->pollMemberCount+1));
-        if (!temp2) {
-            return;
-        }
-        memcpy(temp2, nat->watchData, sizeof(DBusWatch *) *
-                nat->pollMemberCount);
-        free(nat->watchData);
-        nat->watchData = temp2;
-        nat->pollDataSize++;
-    }
-    nat->pollData[nat->pollMemberCount].fd = newFD;
-    nat->pollData[nat->pollMemberCount].revents = 0;
-    nat->pollData[nat->pollMemberCount].events = events;
-    nat->watchData[nat->pollMemberCount] = watch;
-    nat->pollMemberCount++;
-}
-
-static void handleWatchRemove(native_data_t *nat) {
-    int removeFD;
-    unsigned int flags;
-
-    read(nat->controlFdR, &removeFD, sizeof(int));
-    read(nat->controlFdR, &flags, sizeof(unsigned int));
-    short events = dbus_flags_to_unix_events(flags);
-
-    for (int y = 0; y < nat->pollMemberCount; y++) {
-        if ((nat->pollData[y].fd == removeFD) &&
-                (nat->pollData[y].events == events)) {
-            int newCount = --nat->pollMemberCount;
-            // copy the last live member over this one
-            nat->pollData[y].fd = nat->pollData[newCount].fd;
-            nat->pollData[y].events = nat->pollData[newCount].events;
-            nat->pollData[y].revents = nat->pollData[newCount].revents;
-            nat->watchData[y] = nat->watchData[newCount];
-            return;
-        }
-    }
-    ALOGW("WatchRemove given with unknown watch");
-}
-
-static void *eventLoopMain(void *ptr) {
-    native_data_t *nat = (native_data_t *)ptr;
-    JNIEnv *env;
-
-    JavaVMAttachArgs args;
-    char name[] = "BT EventLoop";
-    args.version = nat->envVer;
-    args.name = name;
-    args.group = NULL;
-
-    nat->vm->AttachCurrentThread(&env, &args);
-
-    dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
-            dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
-    dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
-
-    nat->running = true;
-
-    while (1) {
-        for (int i = 0; i < nat->pollMemberCount; i++) {
-            if (!nat->pollData[i].revents) {
-                continue;
-            }
-            if (nat->pollData[i].fd == nat->controlFdR) {
-                char data;
-                while (recv(nat->controlFdR, &data, sizeof(char), MSG_DONTWAIT)
-                        != -1) {
-                    switch (data) {
-                    case EVENT_LOOP_EXIT:
-                    {
-                        dbus_connection_set_watch_functions(nat->conn,
-                                NULL, NULL, NULL, NULL, NULL);
-                        tearDownEventLoop(nat);
-                        nat->vm->DetachCurrentThread();
-
-                        int fd = nat->controlFdR;
-                        nat->controlFdR = 0;
-                        close(fd);
-                        return NULL;
-                    }
-                    case EVENT_LOOP_ADD:
-                    {
-                        handleWatchAdd(nat);
-                        break;
-                    }
-                    case EVENT_LOOP_REMOVE:
-                    {
-                        handleWatchRemove(nat);
-                        break;
-                    }
-                    case EVENT_LOOP_WAKEUP:
-                    {
-                        // noop
-                        break;
-                    }
-                    }
-                }
-            } else {
-                short events = nat->pollData[i].revents;
-                unsigned int flags = unix_events_to_dbus_flags(events);
-                dbus_watch_handle(nat->watchData[i], flags);
-                nat->pollData[i].revents = 0;
-                // can only do one - it may have caused a 'remove'
-                break;
-            }
-        }
-        while (dbus_connection_dispatch(nat->conn) ==
-                DBUS_DISPATCH_DATA_REMAINS) {
-        }
-
-        poll(nat->pollData, nat->pollMemberCount, -1);
-    }
-}
-#endif // HAVE_BLUETOOTH
-
-static jboolean startEventLoopNative(JNIEnv *env, jobject object) {
-    jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
-    event_loop_native_data_t *nat = get_native_data(env, object);
-
-    pthread_mutex_lock(&(nat->thread_mutex));
-
-    nat->running = false;
-
-    if (nat->pollData) {
-        ALOGW("trying to start EventLoop a second time!");
-        pthread_mutex_unlock( &(nat->thread_mutex) );
-        return JNI_FALSE;
-    }
-
-    nat->pollData = (struct pollfd *)calloc(
-            DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd));
-    if (!nat->pollData) {
-        ALOGE("out of memory error starting EventLoop!");
-        goto done;
-    }
-
-    nat->watchData = (DBusWatch **)calloc(
-            DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *));
-    if (!nat->watchData) {
-        ALOGE("out of memory error starting EventLoop!");
-        goto done;
-    }
-
-    nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
-    nat->pollMemberCount = 1;
-
-    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, &(nat->controlFdR))) {
-        ALOGE("Error getting BT control socket");
-        goto done;
-    }
-    nat->pollData[0].fd = nat->controlFdR;
-    nat->pollData[0].events = POLLIN;
-
-    env->GetJavaVM( &(nat->vm) );
-    nat->envVer = env->GetVersion();
-
-    nat->me = env->NewGlobalRef(object);
-
-    if (setUpEventLoop(nat) != JNI_TRUE) {
-        ALOGE("failure setting up Event Loop!");
-        goto done;
-    }
-
-    pthread_create(&(nat->thread), NULL, eventLoopMain, nat);
-    result = JNI_TRUE;
-
-done:
-    if (JNI_FALSE == result) {
-        if (nat->controlFdW) {
-            close(nat->controlFdW);
-            nat->controlFdW = 0;
-        }
-        if (nat->controlFdR) {
-            close(nat->controlFdR);
-            nat->controlFdR = 0;
-        }
-        if (nat->me) env->DeleteGlobalRef(nat->me);
-        nat->me = NULL;
-        if (nat->pollData) free(nat->pollData);
-        nat->pollData = NULL;
-        if (nat->watchData) free(nat->watchData);
-        nat->watchData = NULL;
-        nat->pollDataSize = 0;
-        nat->pollMemberCount = 0;
-    }
-
-    pthread_mutex_unlock(&(nat->thread_mutex));
-#endif // HAVE_BLUETOOTH
-    return result;
-}
-
-static void stopEventLoopNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-
-    pthread_mutex_lock(&(nat->thread_mutex));
-    if (nat->pollData) {
-        char data = EVENT_LOOP_EXIT;
-        ssize_t t = write(nat->controlFdW, &data, sizeof(char));
-        void *ret;
-        pthread_join(nat->thread, &ret);
-
-        env->DeleteGlobalRef(nat->me);
-        nat->me = NULL;
-        free(nat->pollData);
-        nat->pollData = NULL;
-        free(nat->watchData);
-        nat->watchData = NULL;
-        nat->pollDataSize = 0;
-        nat->pollMemberCount = 0;
-
-        int fd = nat->controlFdW;
-        nat->controlFdW = 0;
-        close(fd);
-    }
-    nat->running = false;
-    pthread_mutex_unlock(&(nat->thread_mutex));
-#endif // HAVE_BLUETOOTH
-}
-
-static jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) {
-    jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-
-    pthread_mutex_lock(&(nat->thread_mutex));
-    if (nat->running) {
-        result = JNI_TRUE;
-    }
-    pthread_mutex_unlock(&(nat->thread_mutex));
-
-#endif // HAVE_BLUETOOTH
-    return result;
-}
-
-#ifdef HAVE_BLUETOOTH
-extern DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env);
-
-// Called by dbus during WaitForAndDispatchEventNative()
-static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
-                                      void *data) {
-    native_data_t *nat;
-    JNIEnv *env;
-    DBusError err;
-    DBusHandlerResult ret;
-
-    dbus_error_init(&err);
-
-    nat = (native_data_t *)data;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {
-        ALOGV("%s: not interested (not a signal).", __FUNCTION__);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-    ALOGV("%s: Received signal %s:%s from %s", __FUNCTION__,
-        dbus_message_get_interface(msg), dbus_message_get_member(msg),
-        dbus_message_get_path(msg));
-
-    env->PushLocalFrame(EVENT_LOOP_REFS);
-    if (dbus_message_is_signal(msg,
-                               "org.bluez.Adapter",
-                               "DeviceFound")) {
-        char *c_address;
-        DBusMessageIter iter;
-        jobjectArray str_array = NULL;
-        if (dbus_message_iter_init(msg, &iter)) {
-            dbus_message_iter_get_basic(&iter, &c_address);
-            if (dbus_message_iter_next(&iter))
-                str_array =
-                    parse_remote_device_properties(env, &iter);
-        }
-        if (str_array != NULL) {
-            env->CallVoidMethod(nat->me,
-                                method_onDeviceFound,
-                                env->NewStringUTF(c_address),
-                                str_array);
-        } else
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.Adapter",
-                                     "DeviceDisappeared")) {
-        char *c_address;
-        if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_STRING, &c_address,
-                                  DBUS_TYPE_INVALID)) {
-            ALOGV("... address = %s", c_address);
-            env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
-                                env->NewStringUTF(c_address));
-        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.Adapter",
-                                     "DeviceCreated")) {
-        char *c_object_path;
-        if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_OBJECT_PATH, &c_object_path,
-                                  DBUS_TYPE_INVALID)) {
-            ALOGV("... address = %s", c_object_path);
-            env->CallVoidMethod(nat->me,
-                                method_onDeviceCreated,
-                                env->NewStringUTF(c_object_path));
-        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.Adapter",
-                                     "DeviceRemoved")) {
-        char *c_object_path;
-        if (dbus_message_get_args(msg, &err,
-                                 DBUS_TYPE_OBJECT_PATH, &c_object_path,
-                                 DBUS_TYPE_INVALID)) {
-           ALOGV("... Object Path = %s", c_object_path);
-           env->CallVoidMethod(nat->me,
-                               method_onDeviceRemoved,
-                               env->NewStringUTF(c_object_path));
-        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                      "org.bluez.Adapter",
-                                      "PropertyChanged")) {
-        jobjectArray str_array = parse_adapter_property_change(env, msg);
-        if (str_array != NULL) {
-            /* Check if bluetoothd has (re)started, if so update the path. */
-            jstring property =(jstring) env->GetObjectArrayElement(str_array, 0);
-            const char *c_property = env->GetStringUTFChars(property, NULL);
-            if (!strncmp(c_property, "Powered", strlen("Powered"))) {
-                jstring value =
-                    (jstring) env->GetObjectArrayElement(str_array, 1);
-                const char *c_value = env->GetStringUTFChars(value, NULL);
-                if (!strncmp(c_value, "true", strlen("true")))
-                    nat->adapter = get_adapter_path(nat->conn);
-                env->ReleaseStringUTFChars(value, c_value);
-            }
-            env->ReleaseStringUTFChars(property, c_property);
-
-            env->CallVoidMethod(nat->me,
-                              method_onPropertyChanged,
-                              str_array);
-        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                      "org.bluez.Device",
-                                      "PropertyChanged")) {
-        jobjectArray str_array = parse_remote_device_property_change(env, msg);
-        if (str_array != NULL) {
-            const char *remote_device_path = dbus_message_get_path(msg);
-            env->CallVoidMethod(nat->me,
-                            method_onDevicePropertyChanged,
-                            env->NewStringUTF(remote_device_path),
-                            str_array);
-        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                      "org.bluez.Device",
-                                      "DisconnectRequested")) {
-        const char *remote_device_path = dbus_message_get_path(msg);
-        env->CallVoidMethod(nat->me,
-                            method_onDeviceDisconnectRequested,
-                            env->NewStringUTF(remote_device_path));
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                      "org.bluez.Input",
-                                      "PropertyChanged")) {
-
-        jobjectArray str_array =
-                    parse_input_property_change(env, msg);
-        if (str_array != NULL) {
-            const char *c_path = dbus_message_get_path(msg);
-            env->CallVoidMethod(nat->me,
-                                method_onInputDevicePropertyChanged,
-                                env->NewStringUTF(c_path),
-                                str_array);
-        } else {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        }
-        goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.Network",
-                                     "PropertyChanged")) {
-
-       jobjectArray str_array =
-                   parse_pan_property_change(env, msg);
-       if (str_array != NULL) {
-           const char *c_path = dbus_message_get_path(msg);
-           env->CallVoidMethod(nat->me,
-                               method_onPanDevicePropertyChanged,
-                               env->NewStringUTF(c_path),
-                               str_array);
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.NetworkServer",
-                                     "DeviceDisconnected")) {
-       char *c_address;
-       if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_STRING, &c_address,
-                                  DBUS_TYPE_INVALID)) {
-           env->CallVoidMethod(nat->me,
-                               method_onNetworkDeviceDisconnected,
-                               env->NewStringUTF(c_address));
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.NetworkServer",
-                                     "DeviceConnected")) {
-       char *c_address;
-       char *c_iface;
-       uint16_t uuid;
-
-       if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_STRING, &c_address,
-                                  DBUS_TYPE_STRING, &c_iface,
-                                  DBUS_TYPE_UINT16, &uuid,
-                                  DBUS_TYPE_INVALID)) {
-           env->CallVoidMethod(nat->me,
-                               method_onNetworkDeviceConnected,
-                               env->NewStringUTF(c_address),
-                               env->NewStringUTF(c_iface),
-                               uuid);
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.HealthDevice",
-                                     "ChannelConnected")) {
-       const char *c_path = dbus_message_get_path(msg);
-       const char *c_channel_path;
-       jboolean exists = JNI_TRUE;
-       if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
-                                  DBUS_TYPE_INVALID)) {
-           env->CallVoidMethod(nat->me,
-                               method_onHealthDeviceChannelChanged,
-                               env->NewStringUTF(c_path),
-                               env->NewStringUTF(c_channel_path),
-                               exists);
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.HealthDevice",
-                                     "ChannelDeleted")) {
-
-       const char *c_path = dbus_message_get_path(msg);
-       const char *c_channel_path;
-       jboolean exists = JNI_FALSE;
-       if (dbus_message_get_args(msg, &err,
-                                  DBUS_TYPE_OBJECT_PATH, &c_channel_path,
-                                  DBUS_TYPE_INVALID)) {
-           env->CallVoidMethod(nat->me,
-                               method_onHealthDeviceChannelChanged,
-                               env->NewStringUTF(c_path),
-                               env->NewStringUTF(c_channel_path),
-                               exists);
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    } else if (dbus_message_is_signal(msg,
-                                     "org.bluez.HealthDevice",
-                                     "PropertyChanged")) {
-        jobjectArray str_array =
-                    parse_health_device_property_change(env, msg);
-        if (str_array != NULL) {
-            const char *c_path = dbus_message_get_path(msg);
-            env->CallVoidMethod(nat->me,
-                                method_onHealthDevicePropertyChanged,
-                                env->NewStringUTF(c_path),
-                                str_array);
-       } else {
-           LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-       }
-       goto success;
-    }
-
-    ret = a2dp_event_filter(msg, env);
-    env->PopLocalFrame(NULL);
-    return ret;
-
-success:
-    env->PopLocalFrame(NULL);
-    return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-// Called by dbus during WaitForAndDispatchEventNative()
-DBusHandlerResult agent_event_filter(DBusConnection *conn,
-                                     DBusMessage *msg, void *data) {
-    native_data_t *nat = (native_data_t *)data;
-    JNIEnv *env;
-    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
-        ALOGV("%s: not interested (not a method call).", __FUNCTION__);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-    ALOGI("%s: Received method %s:%s", __FUNCTION__,
-         dbus_message_get_interface(msg), dbus_message_get_member(msg));
-
-    if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
-
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-    env->PushLocalFrame(EVENT_LOOP_REFS);
-
-    if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "Cancel")) {
-        env->CallVoidMethod(nat->me, method_onAgentCancel);
-        // reply
-        DBusMessage *reply = dbus_message_new_method_return(msg);
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
-            goto failure;
-        }
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(reply);
-        goto success;
-
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "Authorize")) {
-        char *object_path;
-        const char *uuid;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_STRING, &uuid,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
-            goto failure;
-        }
-
-        ALOGV("... object_path = %s", object_path);
-        ALOGV("... uuid = %s", uuid);
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onAgentAuthorize,
-                env->NewStringUTF(object_path), env->NewStringUTF(uuid),
-                int(msg));
-
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "OutOfBandAvailable")) {
-        char *object_path;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for OutOfBandData available() method", __FUNCTION__);
-            goto failure;
-        }
-
-        ALOGV("... object_path = %s", object_path);
-
-        bool available =
-            env->CallBooleanMethod(nat->me, method_onAgentOutOfBandDataAvailable,
-                env->NewStringUTF(object_path));
-
-
-        // reply
-        if (available) {
-            DBusMessage *reply = dbus_message_new_method_return(msg);
-            if (!reply) {
-                ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
-                goto failure;
-            }
-            dbus_connection_send(nat->conn, reply, NULL);
-            dbus_message_unref(reply);
-        } else {
-            DBusMessage *reply = dbus_message_new_error(msg,
-                    "org.bluez.Error.DoesNotExist", "OutofBand data not available");
-            if (!reply) {
-                ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
-                goto failure;
-            }
-            dbus_connection_send(nat->conn, reply, NULL);
-            dbus_message_unref(reply);
-        }
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "RequestPinCode")) {
-        char *object_path;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestPinCode,
-                                       env->NewStringUTF(object_path),
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "RequestPasskey")) {
-        char *object_path;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestPasskey,
-                                       env->NewStringUTF(object_path),
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "RequestOobData")) {
-        char *object_path;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestOobData() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestOobData,
-                                       env->NewStringUTF(object_path),
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "DisplayPasskey")) {
-        char *object_path;
-        uint32_t passkey;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_UINT32, &passkey,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onDisplayPasskey,
-                                       env->NewStringUTF(object_path),
-                                       passkey,
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "RequestConfirmation")) {
-        char *object_path;
-        uint32_t passkey;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_UINT32, &passkey,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestConfirmation() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
-                                       env->NewStringUTF(object_path),
-                                       passkey,
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-            "org.bluez.Agent", "RequestPairingConsent")) {
-        char *object_path;
-        if (!dbus_message_get_args(msg, NULL,
-                                   DBUS_TYPE_OBJECT_PATH, &object_path,
-                                   DBUS_TYPE_INVALID)) {
-            ALOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
-            goto failure;
-        }
-
-        dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
-                                       env->NewStringUTF(object_path),
-                                       int(msg));
-        goto success;
-    } else if (dbus_message_is_method_call(msg,
-                  "org.bluez.Agent", "Release")) {
-        // reply
-        DBusMessage *reply = dbus_message_new_method_return(msg);
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply\n", __FUNCTION__);
-            goto failure;
-        }
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(reply);
-        goto success;
-    } else {
-        ALOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
-    }
-
-failure:
-    env->PopLocalFrame(NULL);
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-success:
-    env->PopLocalFrame(NULL);
-    return DBUS_HANDLER_RESULT_HANDLED;
-
-}
-#endif
-
-
-#ifdef HAVE_BLUETOOTH
-
-void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *address = (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    jstring addr;
-
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    ALOGV("... address = %s", address);
-
-    jint result = BOND_RESULT_SUCCESS;
-    if (dbus_set_error_from_message(&err, msg)) {
-        if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) {
-            // Pins did not match, or remote device did not respond to pin
-            // request in time
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_AUTH_FAILED;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationRejected")) {
-            // We rejected pairing, or the remote side rejected pairing. This
-            // happens if either side presses 'cancel' at the pairing dialog.
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_AUTH_REJECTED;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationCanceled")) {
-            // Not sure if this happens
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_AUTH_CANCELED;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.ConnectionAttemptFailed")) {
-            // Other device is not responding at all
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_REMOTE_DEVICE_DOWN;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AlreadyExists")) {
-            // already bonded
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_SUCCESS;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
-                   !strcmp(err.message, "Bonding in progress")) {
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            goto done;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") &&
-                   !strcmp(err.message, "Discover in progress")) {
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_REPEATED_ATTEMPTS;
-        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
-            ALOGV("... error = %s (%s)\n", err.name, err.message);
-            result = BOND_RESULT_AUTH_TIMEOUT;
-        } else {
-            ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
-            result = BOND_RESULT_ERROR;
-        }
-    }
-
-    addr = env->NewStringUTF(address);
-    env->CallVoidMethod(nat->me,
-                        method_onCreatePairedDeviceResult,
-                        addr,
-                        result);
-    env->DeleteLocalRef(addr);
-done:
-    dbus_error_free(&err);
-    free(user);
-}
-
-void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *address= (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    ALOGV("... Address = %s", address);
-
-    jint result = CREATE_DEVICE_SUCCESS;
-    if (dbus_set_error_from_message(&err, msg)) {
-        if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
-            result = CREATE_DEVICE_ALREADY_EXISTS;
-        } else {
-            result = CREATE_DEVICE_FAILED;
-        }
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    }
-    jstring addr = env->NewStringUTF(address);
-    env->CallVoidMethod(nat->me,
-                        method_onCreateDeviceResult,
-                        addr,
-                        result);
-    env->DeleteLocalRef(addr);
-    free(user);
-}
-
-void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *path = (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    ALOGV("... Device Path = %s", path);
-
-    bool result = JNI_TRUE;
-    if (dbus_set_error_from_message(&err, msg)) {
-        LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
-    }
-    jstring jPath = env->NewStringUTF(path);
-    env->CallVoidMethod(nat->me,
-                        method_onDiscoverServicesResult,
-                        jPath,
-                        result);
-    env->DeleteLocalRef(jPath);
-    free(user);
-}
-
-void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    const char *address = (const char *) user;
-    native_data_t *nat = (native_data_t *) n;
-
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    jint channel = -2;
-
-    ALOGV("... address = %s", address);
-
-    if (dbus_set_error_from_message(&err, msg) ||
-        !dbus_message_get_args(msg, &err,
-                               DBUS_TYPE_INT32, &channel,
-                               DBUS_TYPE_INVALID)) {
-        ALOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
-        dbus_error_free(&err);
-    }
-
-done:
-    jstring addr = env->NewStringUTF(address);
-    env->CallVoidMethod(nat->me,
-                        method_onGetDeviceServiceChannelResult,
-                        addr,
-                        channel);
-    env->DeleteLocalRef(addr);
-    free(user);
-}
-
-void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *path = (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    jint result = INPUT_OPERATION_SUCCESS;
-    if (dbus_set_error_from_message(&err, msg)) {
-        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
-            result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
-            result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
-            // TODO():This is flaky, need to change Bluez to add new error codes
-            if (!strcmp(err.message, "Transport endpoint is not connected")) {
-              result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
-            } else {
-              result = INPUT_OPERATION_GENERIC_FAILURE;
-            }
-        } else {
-            result = INPUT_OPERATION_GENERIC_FAILURE;
-        }
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    }
-
-    ALOGV("... Device Path = %s, result = %d", path, result);
-    jstring jPath = env->NewStringUTF(path);
-    env->CallVoidMethod(nat->me,
-                        method_onInputDeviceConnectionResult,
-                        jPath,
-                        result);
-    env->DeleteLocalRef(jPath);
-    free(user);
-}
-
-void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    const char *path = (const char *)user;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    jint result = PAN_OPERATION_SUCCESS;
-    if (dbus_set_error_from_message(&err, msg)) {
-        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
-            result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
-            // TODO():This is flaky, need to change Bluez to add new error codes
-            if (!strcmp(err.message, "Device already connected")) {
-                result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
-            } else if (!strcmp(err.message, "Device not connected")) {
-                result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
-            } else {
-                result = PAN_OPERATION_GENERIC_FAILURE;
-            }
-        } else {
-            result = PAN_OPERATION_GENERIC_FAILURE;
-        }
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    }
-
-    ALOGV("... Pan Device Path = %s, result = %d", path, result);
-    jstring jPath = env->NewStringUTF(path);
-    env->CallVoidMethod(nat->me,
-                        method_onPanDeviceConnectionResult,
-                        jPath,
-                        result);
-    env->DeleteLocalRef(jPath);
-    free(user);
-}
-
-void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
-    ALOGV("%s", __FUNCTION__);
-
-    native_data_t *nat = (native_data_t *)n;
-    DBusError err;
-    dbus_error_init(&err);
-    JNIEnv *env;
-    nat->vm->GetEnv((void**)&env, nat->envVer);
-
-    jint result = HEALTH_OPERATION_SUCCESS;
-    if (dbus_set_error_from_message(&err, msg)) {
-        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".InvalidArgs")) {
-            result = HEALTH_OPERATION_INVALID_ARGS;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".HealthError")) {
-            result = HEALTH_OPERATION_ERROR;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotFound")) {
-            result = HEALTH_OPERATION_NOT_FOUND;
-        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".NotAllowed")) {
-            result = HEALTH_OPERATION_NOT_ALLOWED;
-        } else {
-            result = HEALTH_OPERATION_GENERIC_FAILURE;
-        }
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    }
-
-    jint code = *(int *) user;
-    ALOGV("... Health Device Code = %d, result = %d", code, result);
-    env->CallVoidMethod(nat->me,
-                        method_onHealthDeviceConnectionResult,
-                        code,
-                        result);
-    free(user);
-}
-#endif
-
-static JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"classInitNative", "()V", (void *)classInitNative},
-    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
-    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
-    {"startEventLoopNative", "()V", (void *)startEventLoopNative},
-    {"stopEventLoopNative", "()V", (void *)stopEventLoopNative},
-    {"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative}
-};
-
-int register_android_server_BluetoothEventLoop(JNIEnv *env) {
-    return AndroidRuntime::registerNativeMethods(env,
-            "android/server/BluetoothEventLoop", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
deleted file mode 100644
index 6c11121..0000000
--- a/core/jni/android_server_BluetoothService.cpp
+++ /dev/null
@@ -1,1785 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
-#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
-#define DBUS_INPUT_IFACE BLUEZ_DBUS_BASE_IFC ".Input"
-#define DBUS_NETWORK_IFACE BLUEZ_DBUS_BASE_IFC ".Network"
-#define DBUS_NETWORKSERVER_IFACE BLUEZ_DBUS_BASE_IFC ".NetworkServer"
-#define DBUS_HEALTH_MANAGER_PATH "/org/bluez"
-#define DBUS_HEALTH_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".HealthManager"
-#define DBUS_HEALTH_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".HealthDevice"
-#define DBUS_HEALTH_CHANNEL_IFACE BLUEZ_DBUS_BASE_IFC ".HealthChannel"
-
-#define LOG_TAG "BluetoothService.cpp"
-
-#include "android_bluetooth_common.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "android_util_Binder.h"
-#include "JNIHelp.h"
-#include "jni.h"
-#include "utils/Log.h"
-#include "utils/misc.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#ifdef HAVE_BLUETOOTH
-#include <dbus/dbus.h>
-#include <bluedroid/bluetooth.h>
-#endif
-
-#include <cutils/properties.h>
-
-namespace android {
-
-#define BLUETOOTH_CLASS_ERROR 0xFF000000
-#define PROPERTIES_NREFS 10
-
-#ifdef HAVE_BLUETOOTH
-// We initialize these variables when we load class
-// android.server.BluetoothService
-static jfieldID field_mNativeData;
-static jfieldID field_mEventLoop;
-
-typedef struct {
-    JNIEnv *env;
-    DBusConnection *conn;
-    const char *adapter;  // dbus object name of the local adapter
-} native_data_t;
-
-extern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
-                                                           jobject);
-extern DBusHandlerResult agent_event_filter(DBusConnection *conn,
-                                            DBusMessage *msg,
-                                            void *data);
-void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
-void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
-void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
-void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-void onHealthDeviceConnectionResult(DBusMessage *msg, void *user, void *nat);
-
-
-/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
- *  Perform quick sanity check, if there are any problems return NULL
- */
-static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
-    native_data_t *nat =
-            (native_data_t *)(env->GetIntField(object, field_mNativeData));
-    if (nat == NULL || nat->conn == NULL) {
-        ALOGE("Uninitialized native data\n");
-        return NULL;
-    }
-    return nat;
-}
-#endif
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    field_mNativeData = get_field(env, clazz, "mNativeData", "I");
-    field_mEventLoop = get_field(env, clazz, "mEventLoop",
-            "Landroid/server/BluetoothEventLoop;");
-#endif
-}
-
-/* Returns true on success (even if adapter is present but disabled).
- * Return false if dbus is down, or another serious error (out of memory)
-*/
-static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
-    if (NULL == nat) {
-        ALOGE("%s: out of memory!", __FUNCTION__);
-        return false;
-    }
-    nat->env = env;
-
-    env->SetIntField(object, field_mNativeData, (jint)nat);
-    DBusError err;
-    dbus_error_init(&err);
-    dbus_threads_init_default();
-    nat->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
-    if (dbus_error_is_set(&err)) {
-        ALOGE("Could not get onto the system bus: %s", err.message);
-        dbus_error_free(&err);
-        return false;
-    }
-    dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
-#endif  /*HAVE_BLUETOOTH*/
-    return true;
-}
-
-static const char *get_adapter_path(JNIEnv* env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    event_loop_native_data_t *event_nat =
-        get_EventLoop_native_data(env, env->GetObjectField(object,
-                                                           field_mEventLoop));
-    if (event_nat == NULL)
-        return NULL;
-    return event_nat->adapter;
-#else
-    return NULL;
-#endif
-}
-
-// This function is called when the adapter is enabled.
-static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat =
-        (native_data_t *)env->GetIntField(object, field_mNativeData);
-    event_loop_native_data_t *event_nat =
-        get_EventLoop_native_data(env, env->GetObjectField(object,
-                                                           field_mEventLoop));
-    // Register agent for remote devices.
-    const char *device_agent_path = "/android/bluetooth/remote_device_agent";
-    static const DBusObjectPathVTable agent_vtable = {
-                 NULL, agent_event_filter, NULL, NULL, NULL, NULL };
-
-    if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
-                                              &agent_vtable, event_nat)) {
-        ALOGE("%s: Can't register object path %s for remote device agent!",
-                               __FUNCTION__, device_agent_path);
-        return JNI_FALSE;
-    }
-#endif /*HAVE_BLUETOOTH*/
-    return JNI_TRUE;
-}
-
-static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat =
-               (native_data_t *)env->GetIntField(object, field_mNativeData);
-    if (nat != NULL) {
-        const char *device_agent_path =
-            "/android/bluetooth/remote_device_agent";
-        dbus_connection_unregister_object_path (nat->conn, device_agent_path);
-    }
-#endif /*HAVE_BLUETOOTH*/
-    return JNI_TRUE;
-}
-
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat =
-        (native_data_t *)env->GetIntField(object, field_mNativeData);
-    if (nat) {
-        free(nat);
-        nat = NULL;
-    }
-#endif
-}
-
-static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        return (env->NewStringUTF(get_adapter_path(env, object)));
-    }
-#endif
-    return NULL;
-}
-
-
-static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    DBusMessage *msg = NULL;
-    DBusMessage *reply = NULL;
-    DBusError err;
-    const char *name;
-    jboolean ret = JNI_FALSE;
-
-    native_data_t *nat = get_native_data(env, object);
-    if (nat == NULL) {
-        goto done;
-    }
-
-    dbus_error_init(&err);
-
-    /* Compose the command */
-    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                       get_adapter_path(env, object),
-                                       DBUS_ADAPTER_IFACE, "StartDiscovery");
-
-    if (msg == NULL) {
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        }
-        goto done;
-    }
-
-    /* Send the command. */
-    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-    if (dbus_error_is_set(&err)) {
-         LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-         ret = JNI_FALSE;
-         goto done;
-    }
-
-    ret = JNI_TRUE;
-done:
-    if (reply) dbus_message_unref(reply);
-    if (msg) dbus_message_unref(msg);
-    return ret;
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean stopDiscoveryNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    DBusMessage *msg = NULL;
-    DBusMessage *reply = NULL;
-    DBusError err;
-    const char *name;
-    native_data_t *nat;
-    jboolean ret = JNI_FALSE;
-
-    dbus_error_init(&err);
-
-    nat = get_native_data(env, object);
-    if (nat == NULL) {
-        goto done;
-    }
-
-    /* Compose the command */
-    msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                       get_adapter_path(env, object),
-                                       DBUS_ADAPTER_IFACE, "StopDiscovery");
-    if (msg == NULL) {
-        if (dbus_error_is_set(&err))
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        goto done;
-    }
-
-    /* Send the command. */
-    reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-    if (dbus_error_is_set(&err)) {
-        if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
-                   strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
-            // hcid sends this if there is no active discovery to cancel
-            ALOGV("%s: There was no active discovery to cancel", __FUNCTION__);
-            dbus_error_free(&err);
-        } else {
-            LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
-        }
-        goto done;
-    }
-
-    ret = JNI_TRUE;
-done:
-    if (msg) dbus_message_unref(msg);
-    if (reply) dbus_message_unref(reply);
-    return ret;
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    DBusError err;
-    jbyte *hash, *randomizer;
-    jbyteArray byteArray = NULL;
-    int hash_len, r_len;
-    if (nat) {
-       DBusMessage *reply = dbus_func_args(env, nat->conn,
-                           get_adapter_path(env, object),
-                           DBUS_ADAPTER_IFACE, "ReadLocalOutOfBandData",
-                           DBUS_TYPE_INVALID);
-       if (!reply) return NULL;
-
-       dbus_error_init(&err);
-       if (dbus_message_get_args(reply, &err,
-                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hash_len,
-                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &r_len,
-                                DBUS_TYPE_INVALID)) {
-          if (hash_len == 16 && r_len == 16) {
-               byteArray = env->NewByteArray(32);
-               if (byteArray) {
-                   env->SetByteArrayRegion(byteArray, 0, 16, hash);
-                   env->SetByteArrayRegion(byteArray, 16, 16, randomizer);
-               }
-           } else {
-               ALOGE("readAdapterOutOfBandDataNative: Hash len = %d, R len = %d",
-                                                                  hash_len, r_len);
-           }
-       } else {
-          LOG_AND_FREE_DBUS_ERROR(&err);
-       }
-       dbus_message_unref(reply);
-       return byteArray;
-    }
-#endif
-    return NULL;
-}
-
-static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
-                                         jstring address, jint timeout_ms) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_address = env->GetStringUTFChars(address, NULL);
-        ALOGV("... address = %s", c_address);
-        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
-        const char *capabilities = "DisplayYesNo";
-        const char *agent_path = "/android/bluetooth/remote_device_agent";
-
-        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
-        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
-                                        onCreatePairedDeviceResult, // callback
-                                        context_address,
-                                        eventLoopNat,
-                                        get_adapter_path(env, object),
-                                        DBUS_ADAPTER_IFACE,
-                                        "CreatePairedDevice",
-                                        DBUS_TYPE_STRING, &c_address,
-                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
-                                        DBUS_TYPE_STRING, &capabilities,
-                                        DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(address, c_address);
-        return ret ? JNI_TRUE : JNI_FALSE;
-
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
-                                                jstring address, jint timeout_ms) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_address = env->GetStringUTFChars(address, NULL);
-        ALOGV("... address = %s", c_address);
-        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
-        const char *capabilities = "DisplayYesNo";
-        const char *agent_path = "/android/bluetooth/remote_device_agent";
-
-        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
-        bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
-                                        onCreatePairedDeviceResult, // callback
-                                        context_address,
-                                        eventLoopNat,
-                                        get_adapter_path(env, object),
-                                        DBUS_ADAPTER_IFACE,
-                                        "CreatePairedDeviceOutOfBand",
-                                        DBUS_TYPE_STRING, &c_address,
-                                        DBUS_TYPE_OBJECT_PATH, &agent_path,
-                                        DBUS_TYPE_STRING, &capabilities,
-                                        DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(address, c_address);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
-                                          jstring path,
-                                          jstring pattern, jint attr_id) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-    if (nat && eventLoopNat) {
-        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        ALOGV("... pattern = %s", c_pattern);
-        ALOGV("... attr_id = %#X", attr_id);
-        DBusMessage *reply =
-            dbus_func_args(env, nat->conn, c_path,
-                           DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
-                           DBUS_TYPE_STRING, &c_pattern,
-                           DBUS_TYPE_UINT16, &attr_id,
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(pattern, c_pattern);
-        env->ReleaseStringUTFChars(path, c_path);
-        return reply ? dbus_returns_int32(env, reply) : -1;
-    }
-#endif
-    return -1;
-}
-
-static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
-                                           jstring address) {
-    ALOGV("%s", __FUNCTION__);
-    jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_address = env->GetStringUTFChars(address, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-        ALOGV("... address = %s", c_address);
-        DBusMessage *reply =
-            dbus_func_args_timeout(env, nat->conn, -1,
-                                   get_adapter_path(env, object),
-                                   DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
-                                   DBUS_TYPE_STRING, &c_address,
-                                   DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(address, c_address);
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            } else
-                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return JNI_FALSE;
-        } else {
-            result = JNI_TRUE;
-        }
-        dbus_message_unref(reply);
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
-        bool ret = dbus_func_args_async(env, nat->conn, -1,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        get_adapter_path(env, object),
-                                        DBUS_ADAPTER_IFACE,
-                                        "RemoveDevice",
-                                        DBUS_TYPE_OBJECT_PATH, &c_object_path,
-                                        DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(object_path, c_object_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jint enableNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    return bt_enable();
-#endif
-    return -1;
-}
-
-static jint disableNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    return bt_disable();
-#endif
-    return -1;
-}
-
-static jint isEnabledNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    return bt_is_enabled();
-#endif
-    return -1;
-}
-
-static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
-                                             jstring address, bool confirm,
-                                             int nativeData) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply;
-        if (confirm) {
-            reply = dbus_message_new_method_return(msg);
-        } else {
-            reply = dbus_message_new_error(msg,
-                "org.bluez.Error.Rejected", "User rejected confirmation");
-        }
-
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
-                  "RequestPairingConsent to D-Bus\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
-                         int passkey, int nativeData) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply = dbus_message_new_method_return(msg);
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply to return Passkey code to "
-                 "D-Bus\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        dbus_message_append_args(reply, DBUS_TYPE_UINT32, (uint32_t *)&passkey,
-                                 DBUS_TYPE_INVALID);
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
-                         jbyteArray hash, jbyteArray randomizer, int nativeData) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply = dbus_message_new_method_return(msg);
-        jbyte *h_ptr = env->GetByteArrayElements(hash, NULL);
-        jbyte *r_ptr = env->GetByteArrayElements(randomizer, NULL);
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply to return remote OOB data to "
-                 "D-Bus\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        dbus_message_append_args(reply,
-                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &h_ptr, 16,
-                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &r_ptr, 16,
-                                DBUS_TYPE_INVALID);
-
-        env->ReleaseByteArrayElements(hash, h_ptr, 0);
-        env->ReleaseByteArrayElements(randomizer, r_ptr, 0);
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setAuthorizationNative(JNIEnv *env, jobject object, jstring address,
-                         jboolean val, int nativeData) {
-#ifdef HAVE_BLUETOOTH
-  ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply;
-        if (val) {
-            reply = dbus_message_new_method_return(msg);
-        } else {
-            reply = dbus_message_new_error(msg,
-                    "org.bluez.Error.Rejected", "Authorization rejected");
-        }
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply D-Bus\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
-                         jstring pin, int nativeData) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply = dbus_message_new_method_return(msg);
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply to return PIN code to "
-                 "D-Bus\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        const char *c_pin = env->GetStringUTFChars(pin, NULL);
-
-        dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
-                                 DBUS_TYPE_INVALID);
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        env->ReleaseStringUTFChars(pin, c_pin);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
-                                            jstring address, int nativeData) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg = (DBusMessage *)nativeData;
-        DBusMessage *reply = dbus_message_new_error(msg,
-                "org.bluez.Error.Canceled", "Pairing User Input was canceled");
-        if (!reply) {
-            ALOGE("%s: Cannot create message reply to return cancelUserInput to"
-                 "D-BUS\n", __FUNCTION__);
-            dbus_message_unref(msg);
-            return JNI_FALSE;
-        }
-
-        dbus_connection_send(nat->conn, reply, NULL);
-        dbus_message_unref(msg);
-        dbus_message_unref(reply);
-        return JNI_TRUE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
-                                                    jstring path)
-{
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        reply = dbus_func_args_timeout(env,
-                                   nat->conn, -1, c_path,
-                                   DBUS_DEVICE_IFACE, "GetProperties",
-                                   DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            } else
-                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return NULL;
-        }
-        env->PushLocalFrame(PROPERTIES_NREFS);
-
-        DBusMessageIter iter;
-        jobjectArray str_array = NULL;
-        if (dbus_message_iter_init(reply, &iter))
-           str_array =  parse_remote_device_properties(env, &iter);
-        dbus_message_unref(reply);
-
-        return (jobjectArray) env->PopLocalFrame(str_array);
-    }
-#endif
-    return NULL;
-}
-
-static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-
-        reply = dbus_func_args_timeout(env,
-                                   nat->conn, -1, get_adapter_path(env, object),
-                                   DBUS_ADAPTER_IFACE, "GetProperties",
-                                   DBUS_TYPE_INVALID);
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            } else
-                ALOGE("DBus reply is NULL in function %s", __FUNCTION__);
-            return NULL;
-        }
-        env->PushLocalFrame(PROPERTIES_NREFS);
-
-        DBusMessageIter iter;
-        jobjectArray str_array = NULL;
-        if (dbus_message_iter_init(reply, &iter))
-            str_array = parse_adapter_properties(env, &iter);
-        dbus_message_unref(reply);
-
-        return (jobjectArray) env->PopLocalFrame(str_array);
-    }
-#endif
-    return NULL;
-}
-
-static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
-                                         void *value, jint type) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg;
-        DBusMessageIter iter;
-        dbus_bool_t reply = JNI_FALSE;
-        const char *c_key = env->GetStringUTFChars(key, NULL);
-
-        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                           get_adapter_path(env, object),
-                                           DBUS_ADAPTER_IFACE, "SetProperty");
-        if (!msg) {
-            ALOGE("%s: Can't allocate new method call for GetProperties!",
-                  __FUNCTION__);
-            env->ReleaseStringUTFChars(key, c_key);
-            return JNI_FALSE;
-        }
-
-        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
-        dbus_message_iter_init_append(msg, &iter);
-        append_variant(&iter, type, value);
-
-        // Asynchronous call - the callbacks come via propertyChange
-        reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
-        dbus_message_unref(msg);
-
-        env->ReleaseStringUTFChars(key, c_key);
-        return reply ? JNI_TRUE : JNI_FALSE;
-
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
-                                               jstring value) {
-#ifdef HAVE_BLUETOOTH
-    const char *c_value = env->GetStringUTFChars(value, NULL);
-    jboolean ret =  setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
-    env->ReleaseStringUTFChars(value, (char *)c_value);
-    return ret;
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
-                                               jint value) {
-#ifdef HAVE_BLUETOOTH
-    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
-                                               jint value) {
-#ifdef HAVE_BLUETOOTH
-    return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
-                                               jstring key, void *value, jint type) {
-#ifdef HAVE_BLUETOOTH
-    ALOGV("%s", __FUNCTION__);
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *msg;
-        DBusMessageIter iter;
-        dbus_bool_t reply = JNI_FALSE;
-
-        const char *c_key = env->GetStringUTFChars(key, NULL);
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-
-        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                          c_path, DBUS_DEVICE_IFACE, "SetProperty");
-        if (!msg) {
-            ALOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
-            env->ReleaseStringUTFChars(key, c_key);
-            env->ReleaseStringUTFChars(path, c_path);
-            return JNI_FALSE;
-        }
-
-        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
-        dbus_message_iter_init_append(msg, &iter);
-        append_variant(&iter, type, value);
-
-        // Asynchronous call - the callbacks come via Device propertyChange
-        reply = dbus_connection_send_with_reply(nat->conn, msg, NULL, -1);
-        dbus_message_unref(msg);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        env->ReleaseStringUTFChars(key, c_key);
-
-        return reply ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
-                                                     jstring path, jstring key, jint value) {
-#ifdef HAVE_BLUETOOTH
-    return setDevicePropertyNative(env, object, path, key,
-                                        (void *)&value, DBUS_TYPE_BOOLEAN);
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean setDevicePropertyStringNative(JNIEnv *env, jobject object,
-                                              jstring path, jstring key, jstring value) {
-#ifdef HAVE_BLUETOOTH
-    const char *c_value = env->GetStringUTFChars(value, NULL);
-    jboolean ret = setDevicePropertyNative(env, object, path, key,
-                                           (void *)&c_value, DBUS_TYPE_STRING);
-    env->ReleaseStringUTFChars(value, (char *)c_value);
-    return ret;
-#else
-    return JNI_FALSE;
-#endif
-}
-
-static jboolean createDeviceNative(JNIEnv *env, jobject object,
-                                                jstring address) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_address = env->GetStringUTFChars(address, NULL);
-        ALOGV("... address = %s", c_address);
-        char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
-        strlcpy(context_address, c_address, BTADDR_SIZE);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1,
-                                        onCreateDeviceResult,
-                                        context_address,
-                                        eventLoopNat,
-                                        get_adapter_path(env, object),
-                                        DBUS_ADAPTER_IFACE,
-                                        "CreateDevice",
-                                        DBUS_TYPE_STRING, &c_address,
-                                        DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(address, c_address);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean discoverServicesNative(JNIEnv *env, jobject object,
-                                               jstring path, jstring pattern) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        ALOGV("... Object Path = %s", c_path);
-        ALOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1,
-                                        onDiscoverServicesResult,
-                                        context_path,
-                                        eventLoopNat,
-                                        c_path,
-                                        DBUS_DEVICE_IFACE,
-                                        "DiscoverServices",
-                                        DBUS_TYPE_STRING, &c_pattern,
-                                        DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(path, c_path);
-        env->ReleaseStringUTFChars(pattern, c_pattern);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-#ifdef HAVE_BLUETOOTH
-static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
-    jint *handles;
-    jintArray handleArray = NULL;
-    int len;
-
-    DBusError err;
-    dbus_error_init(&err);
-
-    if (dbus_message_get_args(reply, &err,
-                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
-                              DBUS_TYPE_INVALID)) {
-        handleArray = env->NewIntArray(len);
-        if (handleArray) {
-            env->SetIntArrayRegion(handleArray, 0, len, handles);
-        } else {
-            ALOGE("Null array in extract_handles");
-        }
-    } else {
-        LOG_AND_FREE_DBUS_ERROR(&err);
-    }
-    return handleArray;
-}
-#endif
-
-static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
-                                                jintArray uuids) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    DBusMessage *reply = NULL;
-
-    native_data_t *nat = get_native_data(env, object);
-
-    jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
-    if (!svc_classes) return NULL;
-
-    int len = env->GetArrayLength(uuids);
-    reply = dbus_func_args(env, nat->conn,
-                            get_adapter_path(env, object),
-                            DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
-                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
-                            &svc_classes, len, DBUS_TYPE_INVALID);
-    env->ReleaseIntArrayElements(uuids, svc_classes, 0);
-    return reply ? extract_handles(env, reply) : NULL;
-
-#endif
-    return NULL;
-}
-
-static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
-                                                   jintArray handles) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jint *values = env->GetIntArrayElements(handles, NULL);
-    DBusMessage *msg = NULL;
-    DBusMessage *reply = NULL;
-    if (values == NULL) return JNI_FALSE;
-
-    jsize len = env->GetArrayLength(handles);
-
-    reply = dbus_func_args(env, nat->conn,
-                            get_adapter_path(env, object),
-                            DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
-                            DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
-                            &values, len, DBUS_TYPE_INVALID);
-    env->ReleaseIntArrayElements(handles, values, 0);
-    return reply ? JNI_TRUE : JNI_FALSE;
-#endif
-    return JNI_FALSE;
-}
-
-static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
-        jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_name = env->GetStringUTFChars(name, NULL);
-        ALOGV("... name = %s", c_name);
-        ALOGV("... uuid1 = %llX", uuidMsb);
-        ALOGV("... uuid2 = %llX", uuidLsb);
-        ALOGV("... channel = %d", channel);
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                           get_adapter_path(env, object),
-                           DBUS_ADAPTER_IFACE, "AddRfcommServiceRecord",
-                           DBUS_TYPE_STRING, &c_name,
-                           DBUS_TYPE_UINT64, &uuidMsb,
-                           DBUS_TYPE_UINT64, &uuidLsb,
-                           DBUS_TYPE_UINT16, &channel,
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(name, c_name);
-        return reply ? dbus_returns_uint32(env, reply) : -1;
-    }
-#endif
-    return -1;
-}
-
-static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        ALOGV("... handle = %X", handle);
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                           get_adapter_path(env, object),
-                           DBUS_ADAPTER_IFACE, "RemoveServiceRecord",
-                           DBUS_TYPE_UINT32, &handle,
-                           DBUS_TYPE_INVALID);
-        return reply ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
-                                     jint num_slots) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                           get_adapter_path(env, object),
-                           DBUS_ADAPTER_IFACE, "SetLinkTimeout",
-                           DBUS_TYPE_OBJECT_PATH, &c_object_path,
-                           DBUS_TYPE_UINT32, &num_slots,
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(object_path, c_object_path);
-        return reply ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
-                                        context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
-                                        "Connect",
-                                        DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1, onInputDeviceConnectionResult,
-                                        context_path, eventLoopNat, c_path, DBUS_INPUT_IFACE,
-                                        "Disconnect",
-                                        DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
-                                            jstring src_role, jstring bridge) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        DBusMessage *reply;
-        const char *c_role = env->GetStringUTFChars(src_role, NULL);
-        const char *c_bridge = env->GetStringUTFChars(bridge, NULL);
-        if (value) {
-            ALOGE("setBluetoothTetheringNative true");
-            reply = dbus_func_args(env, nat->conn,
-                                  get_adapter_path(env, object),
-                                  DBUS_NETWORKSERVER_IFACE,
-                                  "Register",
-                                  DBUS_TYPE_STRING, &c_role,
-                                  DBUS_TYPE_STRING, &c_bridge,
-                                  DBUS_TYPE_INVALID);
-        } else {
-            ALOGE("setBluetoothTetheringNative false");
-            reply = dbus_func_args(env, nat->conn,
-                                  get_adapter_path(env, object),
-                                  DBUS_NETWORKSERVER_IFACE,
-                                  "Unregister",
-                                  DBUS_TYPE_STRING, &c_role,
-                                  DBUS_TYPE_INVALID);
-        }
-        env->ReleaseStringUTFChars(src_role, c_role);
-        env->ReleaseStringUTFChars(bridge, c_bridge);
-        return reply ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
-                                       jstring dstRole) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    ALOGE("connectPanDeviceNative");
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        const char *dst = env->GetStringUTFChars(dstRole, NULL);
-
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
-                                    context_path, eventLoopNat, c_path,
-                                    DBUS_NETWORK_IFACE, "Connect",
-                                    DBUS_TYPE_STRING, &dst,
-                                    DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        env->ReleaseStringUTFChars(dstRole, dst);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
-                                     jstring path) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    ALOGE("disconnectPanDeviceNative");
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1,onPanDeviceConnectionResult,
-                                        context_path, eventLoopNat, c_path,
-                                        DBUS_NETWORK_IFACE, "Disconnect",
-                                        DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
-                                                jstring path, jstring address,
-                                                jstring iface) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    ALOGE("disconnectPanServerDeviceNative");
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_address = env->GetStringUTFChars(address, NULL);
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        const char *c_iface = env->GetStringUTFChars(iface, NULL);
-
-        int len = env->GetStringLength(path) + 1;
-        char *context_path = (char *)calloc(len, sizeof(char));
-        strlcpy(context_path, c_path, len);  // for callback
-
-        bool ret = dbus_func_args_async(env, nat->conn, -1,
-                                        onPanDeviceConnectionResult,
-                                        context_path, eventLoopNat,
-                                        get_adapter_path(env, object),
-                                        DBUS_NETWORKSERVER_IFACE,
-                                        "DisconnectDevice",
-                                        DBUS_TYPE_STRING, &c_address,
-                                        DBUS_TYPE_STRING, &c_iface,
-                                        DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(address, c_address);
-        env->ReleaseStringUTFChars(iface, c_iface);
-        env->ReleaseStringUTFChars(path, c_path);
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jstring registerHealthApplicationNative(JNIEnv *env, jobject object,
-                                           jint dataType, jstring role,
-                                           jstring name, jstring channelType) {
-    ALOGV("%s", __FUNCTION__);
-    jstring path = NULL;
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_role = env->GetStringUTFChars(role, NULL);
-        const char *c_name = env->GetStringUTFChars(name, NULL);
-        const char *c_channel_type = env->GetStringUTFChars(channelType, NULL);
-        char *c_path;
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-
-        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                            DBUS_HEALTH_MANAGER_PATH,
-                                            DBUS_HEALTH_MANAGER_IFACE,
-                                            "CreateApplication");
-
-        if (msg == NULL) {
-            ALOGE("Could not allocate D-Bus message object!");
-            return NULL;
-        }
-
-        /* append arguments */
-        append_dict_args(msg,
-                         "DataType", DBUS_TYPE_UINT16, &dataType,
-                         "Role", DBUS_TYPE_STRING, &c_role,
-                         "Description", DBUS_TYPE_STRING, &c_name,
-                         "ChannelType", DBUS_TYPE_STRING, &c_channel_type,
-                         DBUS_TYPE_INVALID);
-
-
-        /* Make the call. */
-        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-
-        env->ReleaseStringUTFChars(role, c_role);
-        env->ReleaseStringUTFChars(name, c_name);
-        env->ReleaseStringUTFChars(channelType, c_channel_type);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-        } else {
-            if (!dbus_message_get_args(reply, &err,
-                                      DBUS_TYPE_OBJECT_PATH, &c_path,
-                                      DBUS_TYPE_INVALID)) {
-                if (dbus_error_is_set(&err)) {
-                    LOG_AND_FREE_DBUS_ERROR(&err);
-                }
-            } else {
-               path = env->NewStringUTF(c_path);
-            }
-            dbus_message_unref(reply);
-        }
-    }
-#endif
-    return path;
-}
-
-static jstring registerSinkHealthApplicationNative(JNIEnv *env, jobject object,
-                                           jint dataType, jstring role,
-                                           jstring name) {
-    ALOGV("%s", __FUNCTION__);
-    jstring path = NULL;
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_role = env->GetStringUTFChars(role, NULL);
-        const char *c_name = env->GetStringUTFChars(name, NULL);
-        char *c_path;
-
-        DBusMessage *msg, *reply;
-        DBusError err;
-        dbus_error_init(&err);
-
-        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
-                                            DBUS_HEALTH_MANAGER_PATH,
-                                            DBUS_HEALTH_MANAGER_IFACE,
-                                            "CreateApplication");
-
-        if (msg == NULL) {
-            ALOGE("Could not allocate D-Bus message object!");
-            return NULL;
-        }
-
-        /* append arguments */
-        append_dict_args(msg,
-                         "DataType", DBUS_TYPE_UINT16, &dataType,
-                         "Role", DBUS_TYPE_STRING, &c_role,
-                         "Description", DBUS_TYPE_STRING, &c_name,
-                         DBUS_TYPE_INVALID);
-
-
-        /* Make the call. */
-        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
-
-        env->ReleaseStringUTFChars(role, c_role);
-        env->ReleaseStringUTFChars(name, c_name);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-        } else {
-            if (!dbus_message_get_args(reply, &err,
-                                      DBUS_TYPE_OBJECT_PATH, &c_path,
-                                      DBUS_TYPE_INVALID)) {
-                if (dbus_error_is_set(&err)) {
-                    LOG_AND_FREE_DBUS_ERROR(&err);
-                }
-            } else {
-                path = env->NewStringUTF(c_path);
-            }
-            dbus_message_unref(reply);
-        }
-    }
-#endif
-    return path;
-}
-
-static jboolean unregisterHealthApplicationNative(JNIEnv *env, jobject object,
-                                                    jstring path) {
-    ALOGV("%s", __FUNCTION__);
-    jboolean result = JNI_FALSE;
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_path = env->GetStringUTFChars(path, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-        DBusMessage *reply =
-            dbus_func_args_timeout(env, nat->conn, -1,
-                                   DBUS_HEALTH_MANAGER_PATH,
-                                   DBUS_HEALTH_MANAGER_IFACE, "DestroyApplication",
-                                   DBUS_TYPE_OBJECT_PATH, &c_path,
-                                   DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(path, c_path);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-        } else {
-            result = JNI_TRUE;
-        }
-    }
-#endif
-    return result;
-}
-
-static jboolean createChannelNative(JNIEnv *env, jobject object,
-                                       jstring devicePath, jstring appPath, jstring config,
-                                       jint code) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
-        const char *c_app_path = env->GetStringUTFChars(appPath, NULL);
-        const char *c_config = env->GetStringUTFChars(config, NULL);
-        int *data = (int *) malloc(sizeof(int));
-        if (data == NULL) return JNI_FALSE;
-
-        *data = code;
-        bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
-                                        data, eventLoopNat, c_device_path,
-                                        DBUS_HEALTH_DEVICE_IFACE, "CreateChannel",
-                                        DBUS_TYPE_OBJECT_PATH, &c_app_path,
-                                        DBUS_TYPE_STRING, &c_config,
-                                        DBUS_TYPE_INVALID);
-
-
-        env->ReleaseStringUTFChars(devicePath, c_device_path);
-        env->ReleaseStringUTFChars(appPath, c_app_path);
-        env->ReleaseStringUTFChars(config, c_config);
-
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jboolean destroyChannelNative(JNIEnv *env, jobject object, jstring devicePath,
-                                     jstring channelPath, jint code) {
-    ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
-    struct event_loop_native_data_t *eventLoopNat =
-            get_EventLoop_native_data(env, eventLoop);
-
-    if (nat && eventLoopNat) {
-        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
-        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
-        int *data = (int *) malloc(sizeof(int));
-        if (data == NULL) return JNI_FALSE;
-
-        *data = code;
-        bool ret = dbus_func_args_async(env, nat->conn, -1, onHealthDeviceConnectionResult,
-                                        data, eventLoopNat, c_device_path,
-                                        DBUS_HEALTH_DEVICE_IFACE, "DestroyChannel",
-                                        DBUS_TYPE_OBJECT_PATH, &c_channel_path,
-                                        DBUS_TYPE_INVALID);
-
-        env->ReleaseStringUTFChars(devicePath, c_device_path);
-        env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
-        return ret ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring devicePath) {
-    ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_device_path = env->GetStringUTFChars(devicePath, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                           c_device_path,
-                           DBUS_HEALTH_DEVICE_IFACE, "GetProperties",
-                           DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(devicePath, c_device_path);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-        } else {
-            DBusMessageIter iter;
-            jobjectArray str_array = NULL;
-            if (dbus_message_iter_init(reply, &iter))
-                str_array = parse_health_device_properties(env, &iter);
-            dbus_message_unref(reply);
-            jstring path = (jstring) env->GetObjectArrayElement(str_array, 1);
-
-            return path;
-        }
-    }
-#endif
-    return NULL;
-}
-
-static jstring getChannelApplicationNative(JNIEnv *env, jobject object, jstring channelPath) {
-    ALOGE("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                                            c_channel_path,
-                                            DBUS_HEALTH_CHANNEL_IFACE, "GetProperties",
-                                            DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-        } else {
-            DBusMessageIter iter;
-            jobjectArray str_array = NULL;
-            if (dbus_message_iter_init(reply, &iter))
-                str_array = parse_health_channel_properties(env, &iter);
-            dbus_message_unref(reply);
-
-            jint len = env->GetArrayLength(str_array);
-
-            jstring name, path;
-            const char *c_name;
-
-            for (int i = 0; i < len; i+=2) {
-                name = (jstring) env->GetObjectArrayElement(str_array, i);
-                c_name = env->GetStringUTFChars(name, NULL);
-
-                if (!strcmp(c_name, "Application")) {
-                    path = (jstring) env->GetObjectArrayElement(str_array, i+1);
-                    env->ReleaseStringUTFChars(name, c_name);
-                    return path;
-                }
-                env->ReleaseStringUTFChars(name, c_name);
-            }
-        }
-    }
-#endif
-    return NULL;
-}
-
-static jboolean releaseChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
-        DBusError err;
-        dbus_error_init(&err);
-
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                                            c_channel_path,
-                                            DBUS_HEALTH_CHANNEL_IFACE, "Release",
-                                            DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
-        return reply ? JNI_TRUE : JNI_FALSE;
-    }
-#endif
-    return JNI_FALSE;
-}
-
-static jobject getChannelFdNative(JNIEnv *env, jobject object, jstring channelPath) {
-    ALOGV("%s", __FUNCTION__);
-#ifdef HAVE_BLUETOOTH
-    native_data_t *nat = get_native_data(env, object);
-    if (nat) {
-        const char *c_channel_path = env->GetStringUTFChars(channelPath, NULL);
-        int32_t fd;
-        DBusError err;
-        dbus_error_init(&err);
-
-        DBusMessage *reply = dbus_func_args(env, nat->conn,
-                                            c_channel_path,
-                                            DBUS_HEALTH_CHANNEL_IFACE, "Acquire",
-                                            DBUS_TYPE_INVALID);
-        env->ReleaseStringUTFChars(channelPath, c_channel_path);
-
-        if (!reply) {
-            if (dbus_error_is_set(&err)) {
-                LOG_AND_FREE_DBUS_ERROR(&err);
-            }
-            return NULL;
-        }
-
-        fd = dbus_returns_unixfd(env, reply);
-        if (fd == -1) return NULL;
-
-        int flags = fcntl(fd, F_GETFL);
-        if (flags < 0) {
-           ALOGE("Can't get flags with fcntl(): %s (%d)",
-                                strerror(errno), errno);
-           releaseChannelFdNative(env, object, channelPath);
-           close(fd);
-           return NULL;
-        }
-
-        flags &= ~O_NONBLOCK;
-        int status = fcntl(fd, F_SETFL, flags);
-        if (status < 0) {
-           ALOGE("Can't set flags with fcntl(): %s (%d)",
-               strerror(errno), errno);
-           releaseChannelFdNative(env, object, channelPath);
-           close(fd);
-           return NULL;
-        }
-
-        // Create FileDescriptor object
-        jobject fileDesc = jniCreateFileDescriptor(env, fd);
-        if (fileDesc == NULL) {
-            // FileDescriptor constructor has thrown an exception
-            releaseChannelFdNative(env, object, channelPath);
-            close(fd);
-            return NULL;
-        }
-
-        // Wrap it in a ParcelFileDescriptor
-        jobject parcelFileDesc = newParcelFileDescriptor(env, fileDesc);
-        if (parcelFileDesc == NULL) {
-            // ParcelFileDescriptor constructor has thrown an exception
-            releaseChannelFdNative(env, object, channelPath);
-            close(fd);
-            return NULL;
-        }
-
-        return parcelFileDesc;
-    }
-#endif
-    return NULL;
-}
-
-
-
-static JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-    {"classInitNative", "()V", (void*)classInitNative},
-    {"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
-    {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
-    {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
-    {"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
-    {"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
-
-    {"isEnabledNative", "()I", (void *)isEnabledNative},
-    {"enableNative", "()I", (void *)enableNative},
-    {"disableNative", "()I", (void *)disableNative},
-
-    {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
-    {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
-      (void *)getDevicePropertiesNative},
-    {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
-      (void *)setAdapterPropertyStringNative},
-    {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
-      (void *)setAdapterPropertyBooleanNative},
-    {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
-      (void *)setAdapterPropertyIntegerNative},
-
-    {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
-    {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
-
-    {"readAdapterOutOfBandDataNative", "()[B", (void *)readAdapterOutOfBandDataNative},
-    {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
-    {"createPairedDeviceOutOfBandNative", "(Ljava/lang/String;I)Z",
-                                    (void *)createPairedDeviceOutOfBandNative},
-    {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
-    {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
-    {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
-      (void *)getDeviceServiceChannelNative},
-
-    {"setPairingConfirmationNative", "(Ljava/lang/String;ZI)Z",
-            (void *)setPairingConfirmationNative},
-    {"setPasskeyNative", "(Ljava/lang/String;II)Z", (void *)setPasskeyNative},
-    {"setRemoteOutOfBandDataNative", "(Ljava/lang/String;[B[BI)Z", (void *)setRemoteOutOfBandDataNative},
-    {"setAuthorizationNative", "(Ljava/lang/String;ZI)Z", (void *)setAuthorizationNative},
-    {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
-    {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
-            (void *)cancelPairingUserInputNative},
-    {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
-            (void *)setDevicePropertyBooleanNative},
-    {"setDevicePropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
-            (void *)setDevicePropertyStringNative},
-    {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
-    {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
-    {"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
-    {"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
-    {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
-    {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
-    {"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
-    // HID functions
-    {"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},
-    {"disconnectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectInputDeviceNative},
-
-    {"setBluetoothTetheringNative", "(ZLjava/lang/String;Ljava/lang/String;)Z",
-              (void *)setBluetoothTetheringNative},
-    {"connectPanDeviceNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
-              (void *)connectPanDeviceNative},
-    {"disconnectPanDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectPanDeviceNative},
-    {"disconnectPanServerDeviceNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z",
-              (void *)disconnectPanServerDeviceNative},
-    // Health function
-    {"registerHealthApplicationNative",
-              "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-              (void *)registerHealthApplicationNative},
-    {"registerHealthApplicationNative",
-            "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void *)registerSinkHealthApplicationNative},
-
-    {"unregisterHealthApplicationNative", "(Ljava/lang/String;)Z",
-              (void *)unregisterHealthApplicationNative},
-    {"createChannelNative", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Z",
-              (void *)createChannelNative},
-    {"destroyChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
-              (void *)destroyChannelNative},
-    {"getMainChannelNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getMainChannelNative},
-    {"getChannelApplicationNative", "(Ljava/lang/String;)Ljava/lang/String;",
-              (void *)getChannelApplicationNative},
-    {"getChannelFdNative", "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;", (void *)getChannelFdNative},
-    {"releaseChannelFdNative", "(Ljava/lang/String;)Z", (void *)releaseChannelFdNative},
-};
-
-
-int register_android_server_BluetoothService(JNIEnv *env) {
-    return AndroidRuntime::registerNativeMethods(env,
-                "android/server/BluetoothService", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 5739cbe..60f8c48 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -481,24 +481,6 @@
     }
 }
 
-static void Surface_freezeDisplay(
-        JNIEnv* env, jobject clazz, jint display)
-{
-    int err = SurfaceComposerClient::freezeDisplay(display, 0);
-    if (err < 0) {
-        doThrowIAE(env);
-    }
-}
-
-static void Surface_unfreezeDisplay(
-        JNIEnv* env, jobject clazz, jint display)
-{
-    int err = SurfaceComposerClient::unfreezeDisplay(display, 0);
-    if (err < 0) {
-        doThrowIAE(env);
-    }
-}
-
 class ScreenshotPixelRef : public SkPixelRef {
 public:
     ScreenshotPixelRef(SkColorTable* ctable) {
@@ -655,28 +637,6 @@
     }
 }
 
-static void Surface_freeze(
-        JNIEnv* env, jobject clazz)
-{
-    const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
-    if (surface == 0) return;
-    status_t err = surface->freeze();
-    if (err<0 && err!=NO_INIT) {
-        doThrowIAE(env);
-    }
-}
-
-static void Surface_unfreeze(
-        JNIEnv* env, jobject clazz)
-{
-    const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
-    if (surface == 0) return;
-    status_t err = surface->unfreeze();
-    if (err<0 && err!=NO_INIT) {
-        doThrowIAE(env);
-    }
-}
-
 static void Surface_setFlags(
         JNIEnv* env, jobject clazz, jint flags, jint mask)
 {
@@ -735,18 +695,6 @@
     }
 }
 
-static void Surface_setFreezeTint(
-        JNIEnv* env, jobject clazz,
-        jint tint)
-{
-    const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
-    if (surface == 0) return;
-    status_t err = surface->setFreezeTint(tint);
-    if (err<0 && err!=NO_INIT) {
-        doThrowIAE(env);
-    }
-}
-
 static void Surface_setWindowCrop(JNIEnv* env, jobject thiz, jobject crop)
 {
     const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz));
@@ -892,8 +840,6 @@
     {"openTransaction",     "()V",  (void*)Surface_openTransaction },
     {"closeTransaction",    "()V",  (void*)Surface_closeTransaction },
     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
-    {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
-    {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
     {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },
     {"screenshot",          "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
     {"setLayer",            "(I)V", (void*)Surface_setLayer },
@@ -901,13 +847,10 @@
     {"setSize",             "(II)V",(void*)Surface_setSize },
     {"hide",                "()V",  (void*)Surface_hide },
     {"show",                "()V",  (void*)Surface_show },
-    {"freeze",              "()V",  (void*)Surface_freeze },
-    {"unfreeze",            "()V",  (void*)Surface_unfreeze },
     {"setFlags",            "(II)V",(void*)Surface_setFlags },
     {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion },
     {"setAlpha",            "(F)V", (void*)Surface_setAlpha },
     {"setMatrix",           "(FFFF)V",  (void*)Surface_setMatrix },
-    {"setFreezeTint",       "(I)V",  (void*)Surface_setFreezeTint },
     {"readFromParcel",      "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },
     {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
     {"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cdc5ad4..9253f24 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -121,6 +121,7 @@
 
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" />
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" />
+    <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" />
 
     <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
     <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
@@ -508,6 +509,11 @@
         android:permissionGroup="android.permission-group.NETWORK"
         android:protectionLevel="signature|system" />
 
+    <!-- @hide -->
+    <permission android:name="android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"
+        android:permissionGroup="android.permission-group.NETWORK"
+        android:protectionLevel="signature|system" />
+
     <!-- ================================== -->
     <!-- Permissions for accessing accounts -->
     <!-- ================================== -->
@@ -1409,6 +1415,11 @@
         android:description="@string/permdesc_devicePower"
         android:protectionLevel="signature" />
 
+   <!-- Allows low-level access to tun tap driver -->
+    <permission android:name="android.permission.NET_TUNNELING"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature" />
+
     <!-- Run as a manufacturer test application, running as the root user.
          Only available when the device is running in manufacturer test mode. -->
     <permission android:name="android.permission.FACTORY_TEST"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index d2f1b8d..0a490eb 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"የስርዓቱን ውስጣዊ ሁናቴ ለመበርበር ለመተግበሪያው ይፈቅዳሉ፡፡ በተለምዶ የማያስፈልጋቸውን ብዙ አይነት የግል እና የደህንነት መረጃዎችን ተንኮል አዘል  መተግበሪያዎች ሊበረብሩ ይችላሉ፡፡"</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"የማያ ይዘት ሰርስረህ አውጣ"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"የነቃ መስኮት ይዘትን ለመበርበር ለመተግበሪያው ይፈቅዳሉ፡፡ ጠቅላላውን የመስኮት ይዘት ለመበርበር እና ከይለፍ ቃል በስተቀር ሁሉንም ጽሑፉን ለማየት ጎጂ መተግበሪያዎች ይችላሉ፡፡"</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"የመስኮት መረጃን አምጣ"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"አንድ መተግበሪያ ከመስኮት አቀናባሪው ሆኖ ስለመስኮቱ መረጃ እንዲያመጣ ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ለውስጣዊ ስርዓት ጥቅም የታሰበ መረጃን ሊወስዱ ይችላሉ።"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ክስተቶችን አጣራ"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"አንድ መተግበሪያ የሁሉንም ተጠቃሚዎች ክስተቶች ከመላካቸው በፊት እነሱን የሚያጣራ የግቤት ማጣሪያ እንዲመዘግብ ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች ተጠቃሚው ጣልቃ ሳይገባ የስርዓቱን በይነገጽ ሊቆጣጠሩት ይችላሉ።"</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"ከፊል ዝጋ"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"የእንቅስቃሴውን አደራጅ ወደ ዝጋ ሁነታ አስቀምጥ።ሙሉ ለሙሉ ዝጋ አያከናውንም።"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"የትግበራ መቀያየርን ተከላከል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 589619c..ee3b437 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"للسماح للتطبيق باسترداد الحالة الداخلية للنظام. قد تسترد التطبيقات الضارة مجموعة كبيرة من المعلومات الخاصة والآمنة التي لا حاجة لها في العادة على الإطلاق."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"استرداد محتوى الشاشة"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"للسماح للتطبيق باسترداد محتوى النافذة النشطة. يمكن للبرامج الضارة استرداد محتوى النافذة بالكامل وفحص جميع النصوص الموجودة بها باستثناء كلمات المرور."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"استرداد معلومات النوافذ"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"للسماح لأحد التطبيقات باستعادة معلومات حول النوافذ من مدير النوافذ. يمكن أن تستعيد التطبيقات الضارة معلومات الغرض منها استخدام النظام الداخلي."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"تصفية الأحداث"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"للسماح لأحد التطبيقات بتسجيل فلتر إدخال يعمل على تصفية مجموعة البث من جميع أحداث المستخدمين قبل إرسالها. يمكن أن يتحكم برنامج ضار في واجهة المستخدم النظام بدون تدخل المستخدم."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"إيقاف تشغيل جزئي"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"لوضع مدير الأنشطة في حالة إيقاف التشغيل. لا يتم تنفيذ إيقاف تشغيل كامل."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"منع التبديل بين التطبيقات"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4c8787f..b8a5e84 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Permet que l\'aplicació recuperi l\'estat intern del sistema. Les aplicacions malicioses poden recuperar una àmplia gamma d\'informació privada i de seguretat que normalment no haurien de necessitar mai."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"recuperació del contingut de la pantalla"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permet que l\'aplicació recuperi el contingut de la finestra activa. Les aplicacions malicioses poden recuperar el contingut de tota la finestra i examinar-ne tot el text, excepte les contrasenyes."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"recupera informació de les finestres"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permet que una aplicació recuperi informació sobre les finestres del gestor de finestres. Aplicacions malicioses podrien recuperar informació dirigida a la utilització per part del sistema intern."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtra els esdeveniments"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permet que una aplicació registre un filtre d\'entrada per a l\'emissió de tots els esdeveniments d\'usuari abans no s\'enviïn. Aplicacions malicioses podrien controlar la IU del sistema sense la intervenció de l\'usuari."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"apagar parcialment"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Posa el gestor d\'activitats en estat d\'apagada. No fa una apagada completa."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir els canvis d\'aplicació"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 64a78947..89f2e1e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Tillader, at appen kan hente systemets interne tilstand. Ondsindede apps kan hente en lang række fortrolige og beskyttede oplysninger, som de normalt aldrig ville have brug for."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hente skærmindhold"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tillader, at appen kan hente indholdet i det aktive vindue. Ondsindede apps kan hente al indholdet i vinduet og undersøge al dens tekst med undtagelse af adgangskoder."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hent oplysninger om vinduer"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tillader, at en applikation henter oplysninger om vinduerne i vinduesadministratoren. Skadelige apps kan muligvis hente oplysninger, der er beregnet til intern systembrug."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrer begivenheder"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Tillader, at en applikation registrerer et inputfilter, som filtrerer alle brugeres strøm, før disse afsendes. Skadelige apps kan muligvis kontrollere systemets grænseflade uden brugerens deltagelse."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"delvis lukning"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Sætter aktivitetsadministratoren i lukningstilstand. Lukker ikke helt ned."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"undgå programskift"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 1ec6144..02017c4 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Ermöglicht der App, den internen Systemstatus abzurufen. Schädliche Apps können so eine Vielzahl an privaten und geschützten Daten abrufen, die sie in der Regel nicht benötigen."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"Bildschirminhalt abrufen"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ermöglicht der App, den Inhalt des aktiven Fensters abzurufen. Schädliche Apps können so den gesamten Fensterinhalt abrufen und mit Ausnahme von Passwörtern den gesamten Text auswerten."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"Fensterinformationen abrufen"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Ermöglicht einer App, Informationen über die Fenster vom Fenster-Manager abzurufen. Schädliche Apps können Informationen abrufen, die für die systeminterne Nutzung gedacht sind."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"Ereignisse filtern"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Ermöglicht einer App, einen Eingabefilter zu registrieren, der den Stream aller Nutzerereignisse vor ihrem Versand filtert. Eine schädliche App kann die System-UI ohne Eingriff des Nutzers kontrollieren."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"partielles Herunterfahren"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Versetzt den Aktivitätsmanager in einen heruntergefahrenen Zustand. Führt kein vollständiges Herunterfahren aus."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"App-Wechsel verhindern"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ba4d96e..3116317 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Επιτρέπει στην  εφαρμογή την ανάκτηση της εσωτερικής κατάστασης του συστήματος. Τυχόν κακόβουλες εφαρμογές ενδέχεται να ανακτήσουν μεγάλη ποικιλία ιδιωτικών πληροφοριών και πληροφοριών ασφάλειας οι οποίες δεν θα έπρεπε να τους είναι απαραίτητες υπό φυσιολογικές συνθήκες."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ανάκτηση περιεχομένου οθόνης"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Επιτρέπει στην εφαρμογή την ανάκτηση του περιεχομένου του ενεργού παραθύρου. Τυχόν κακόβουλες εφαρμογές ενδέχεται να ανακτήσουν ολόκληρο το περιεχόμενο του παραθύρου και να εξετάσουν ολόκληρο το κείμενό του εκτός από τους κωδικούς πρόσβασης."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ανάκτηση πληροφοριών παραθύρων"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Επιτρέπει σε μια εφαρμογή να ανακτήσει πληροφορίες σχετικά με τα παράθυρα από το διαχειριστή παραθύρων. Οι κακόβουλες εφαρμογές ενδέχεται να ανακτήσουν πληροφορίες που προορίζονται για την εσωτερική χρήση του συστήματος."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"φιλτράρισμα συμβάντων"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Επιτρέπει σε μια εφαρμογή να καταγράφει ένα φίλτρο εισαγωγής, το οποίο φιλτράρει τη ροή όλων των συμβάντων χρήστη πριν την αποστολή τους. Μια κακόβουλη εφαρμογή μπορεί να ελέγξει τη διεπαφή του συστήματος χωρίς την παρέμβαση του χρήστη."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"μερικός τερματισμός λειτουργίας"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Θέτει το πρόγραμμα διαχείρισης δραστηριοτήτων σε κατάσταση τερματισμού λειτουργιών. Δεν εκτελεί πλήρη τερματισμό λειτουργιών."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"αποτροπή εναλλαγών εφαρμογών"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index faeb3fa..6763ed7 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Allows the app to retrieve the internal state of the system. Malicious apps may retrieve a wide variety of private and secure information that they should never normally need."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"retrieve screen content"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Allows the app to retrieve the content of the active window. Malicious apps may retrieve the entire window content and examine all its text except passwords."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"retrieve window info"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Allows an application to retrieve information about the windows from the window manager. Malicious apps may retrieve information that is intended for internal system usage."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filter events"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Allows an application to register an input filter which filters the stream of all user events before they are dispatched. Malicious app may control the system UI without user intervention."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"partial shutdown"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Puts the activity manager into a shut-down state. Does not perform a complete shut down."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"prevent app switches"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 915c8ad..446e20ba 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Permite que la aplicación recupere el estado interno del sistema. Las aplicaciones maliciosas pueden recuperar una amplia variedad de información privada y segura que normalmente no necesitarían."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"recuperar contenido de la pantalla"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permite que la aplicación recupere el contenido de la ventana activa. Las aplicaciones maliciosas pueden recuperar el contenido completo de la ventana y examinar todo el texto, excepto las contraseñas."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"Recuperar información de ventanas"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permite a una aplicación recuperar la información del administrador de ventanas relacionada con estas. Las aplicaciones maliciosas pueden recuperar información destinada al uso interno del sistema."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"Filtrar eventos"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permite a una aplicación registrar un filtro de entrada que filtre la transmisión de todos los eventos del usuario antes de ser enviados. Las aplicaciones maliciosas pueden controlar la IU del sistema sin la intervención del usuario."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"cierre parcial"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Pone al administrador de la actividad en estado de cierre. No realiza un cierre completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir conmutadores de aplicación"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 14d4095..c765056 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Permite que la aplicación recupere el estado interno del sistema. Las aplicaciones malintencionadas pueden usar este permiso para recuperar una gran variedad de información protegida y privada que normalmente no deberían necesitar."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"recuperar contenido de la pantalla"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permite que la aplicación recupere el contenido de la ventana activa. Las aplicaciones malintencionadas pueden recuperar todo el contenido de la ventana y analizar todo el texto de la misma, excepto las contraseñas."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"recuperar información de ventanas"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permite que una aplicación recupere información sobre las ventanas del administrador de ventanas. Las aplicaciones malintencionadas pueden recuperar información destinada al uso interno del sistema."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrar eventos"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permite que una aplicación registre un filtro de entrada que filtre el flujo de los eventos del usuario antes de que se envíe. Las aplicaciones malintencionadas pueden controlar la interfaz del sistema sin la intervención del usuario."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"cierre parcial"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Pone el administrador de actividades en estado de cierre. No realiza un cierre completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"evitar cambios de aplicación"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 1a272a1..aaed050 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"به برنامه اجازه می‎دهد تا وضعیت داخلی سیستم را بازیابی کند. برنامه‎های مخرب می‎توانند انواع مختلفی از اطلاعات خصوصی و امن را که معمولا به آن‌ها نیاز ندارند، بازیابی کنند."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"بازیابی محتوای صفحه"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"به برنامه اجازه می‎دهد تا محتوای پنجره فعال را بازیابی کند. برنامه‎های مخرب می‎توانند کل محتوای پنجره را بازیابی کنند و همه متن آنرا به غیر از گذرواژه‎ها امتحان کنند."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"بازیابی اطلاعات پنجره"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"به یک برنامه کاربردی اجازه می‌دهد که اطلاعات مربوط به پنجره‌ها را از مدیریت پنجره بازیابی کند. برنامه‌های کاربردی مخرب ممکن است اطلاعاتی که برای استفاده سیستم داخلی درنظر گرفته شده‌اند را بازیابی کنند."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"فیلتر کردن رویدادها"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"به یک برنامه کاربردی اجازه می‌دهد یک فیلتر ورودی را که جریان تمام رویدادهای کاربران را قبل از ارسال شدن فیلتر می‌کند، ثبت نماید. برنامه‌ کاربردی مخرب ممکن است رابط کاربری سیستم را بدون مداخله کاربر، کنترل کند."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"خاموش شدن جزئی"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"مدیر فعالیت را در حالت خاموشی قرار می‌دهد. خاموشی را به صورت کامل انجام نمی‌دهد."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ممانعت از جابجایی برنامه"</string>
@@ -729,7 +725,7 @@
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"سیم کارت قفل شد."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت..."</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. "\n\n"لطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کرده اید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کرده‌اید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"پین را<xliff:g id="NUMBER_0">%d</xliff:g>  بار اشتباه تایپ کرده‎اید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که برای بازگشایی قفل رایانه لوحی خود به Google وارد شوید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر از شما خواسته می‎شود که برای بازگشایی قفل گوشی خود به برنامه Google وارد شوید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
@@ -738,7 +734,7 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"شما به اشتباه اقدام به باز کردن قفل <xliff:g id="NUMBER">%d</xliff:g> رایانه لوحی کرده‌اید. رایانه لوحی در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"در <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"الگو را فراموش کرده اید؟"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"الگو را فراموش کرده‌اید؟"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"بازگشایی قفل حساب"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"تلاش‎های زیادی برای کشیدن الگو صورت گرفته است"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"برای بازگشایی قفل، با حساب Google خود وارد سیستم شوید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index b0bec56..edf133a 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Antaa sovelluksen noutaa järjestelmän sisäisen tilan. Haitalliset sovellukset voivat noutaa paljon yksityisiä ja suojattuja tietoja, joita niiden ei pitäisi tarvita normaalisti."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"nouda näytön sisältö"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Antaa sovelluksen noutaa aktiivisen ikkunan sisällön. Haitalliset sovellukset voivat noutaa koko ikkunan sisällön ja tarkastella sen kaikkea tekstiä lukuun ottamatta salasanoja."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"nouda ikkunoiden tietoja"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Antaa sovelluksen noutaa ikkunoiden tietoja ikkunanhallinnasta. Haitalliset sovellukset voivat noutaa tietoja, jotka on tarkoitettu järjestelmän sisäiseen käyttöön."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"suodata tapahtumat"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Antaa sovelluksen rekisteröidä syöttösuodattimen, joka suodattaa kaikkien käyttäjätapahtumien streamin ennen tapahtumien näyttämistä. Haitalliset sovellukset voivat hallita järjestelmän käyttöliittymää ilman käyttäjän lupaa."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"sulje puhelin osittain"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Asettaa toimintojen hallinnan sulkeutumistilaan. Ei sulje puhelinta kokonaan."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"estä sovellusten vaihto"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b5bc390..58ae361 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Permet à l\'application de récupérer l\'état interne du système. Des applications malveillantes peuvent récupérer de nombreuses informations confidentielles et sécurisées dont elles ne devraient pas avoir besoin normalement."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"récupérer le contenu de l\'écran"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permet à l\'application de récupérer le contenu de la fenêtre active. Des applications malveillantes peuvent exploiter cette fonctionnalité pour récupérer et lire la totalité du contenu de la fenêtre, à l\'exception des mots de passe."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"récupérer les informations sur les fenêtres"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permet à une application de récupérer les informations sur les fenêtres depuis le gestionnaire de fenêtres. Des applications malveillantes peuvent récupérer des informations destinées à un usage interne du système."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrer les événements"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permet à une application d\'enregistrer un filtre d\'entrée pour filtrer le flux de tous les événements des utilisateurs avant qu\'ils ne soient traités. Des applications malveillantes peuvent contrôler l\'interface utilisateur du système sans l\'intervention de l\'utilisateur."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"arrêt partiel"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Place le gestionnaire d\'activités en état d\'arrêt. N\'effectue pas un arrêt complet."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"empêcher les changements d\'applications"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ba24521..41f34f6 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Omogućuje aplikaciji dohvaćanje unutarnjeg stanja sustava. Zlonamjerne aplikacije mogu dohvatiti razne privatne i sigurnosne podatke koje im inače nikada ne bi trebale biti potrebne."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"dohvaćanje sadržaja zaslona"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Omogućuje aplikaciji dohvaćanje sadržaja aktivnog prozora. Zlonamjerne aplikacije mogu dohvatiti sav sadržaj prozora i pregledati sav njegov tekst osim zaporki."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"dohvaćanje informacija o prozoru"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Aplikaciji omogućuje dohvaćanje informacija o prozorima iz upravitelja prozora. Zlonamjerne aplikacije mogu dohvaćati informacije koje su namijenjene za internu uporabu sustava."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtriranje događaja"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Aplikaciji omogućuje registraciju ulaznog filtra koji filtrira strujanje svih korisničkih događaja prije otpreme. Zlonamjerne aplikacije mogu kontrolirati korisničko sučelje sustava bez znanja korisnika."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"djelomično isključivanje"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Postavlja upravitelja za aktivnost u stanje mirovanja. Ne isključuje ga u potpunosti."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"sprečavanje promjene aplikacije"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 834bca3..f4526fa 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Lehetővé teszi az alkalmazás számára, hogy lekérje a rendszer belső állapotát. A rosszindulatú programok lekérhetnek számos olyan privát és biztonságos adatot, amelyekre normál esetben soha nincs szükségük."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"a képernyő tartalmának lekérése"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Lehetővé teszi az alkalmazás számára az aktív ablak tartalmának letöltését. A rosszindulatú alkalmazások letölthetik az ablak teljes tartalmát, és a jelszavak kivételével az összes szöveget megvizsgálhatják."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ablakkal kapcsolatos információk lekérése"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Lehetővé teszi, hogy az alkalmazás információkat kérjen le az ablakkezelőben lévő ablakokkal kapcsolatban. A rosszindulatú alkalmazások belső rendszerhasználathoz szükséges információkat kérhetnek le."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"események szűrése"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Lehetővé teszi az alkalmazás számára, hogy egy bemeneti szűrőt használjon, amely megszűri a falon megjelenő felhasználói eseményeket, még mielőtt megjelennének. A rosszindulatú alkalmazások felhasználói beavatkozás nélkül irányíthatják a rendszer kezelőfelületét."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"részleges rendszerleállítás"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Leállítás állapotba helyezi a tevékenységkezelőt. Nem hajtja végre a teljes leállítást."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"alkalmazásváltás megakadályozása"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 52c69a9..c492e2d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Consente all\'applicazione di recuperare lo stato interno del sistema. Le applicazioni dannose potrebbero recuperare una vasta gamma di informazioni private e protette di cui normalmente non dovrebbero mai avere bisogno."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"recupero dei contenuti della schermata"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Consente all\'applicazione di recuperare i contenuti della finestra attiva. Le applicazioni dannose potrebbero recuperare l\'intero contenuto della finestra ed esaminare tutto il testo, tranne le password."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"recupero di informazioni sulle finestre"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Consente a un\'applicazione di recuperare informazioni sulle finestre dalla gestione finestre. Le applicazioni dannose potrebbero recuperare informazioni destinate all\'utilizzo da parte del sistema interno."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtro eventi"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Consente a un\'applicazione di registrare un filtro di ingresso che filtra lo stream di tutti gli eventi degli utenti prima che vengano inviati. Un\'applicazione dannosa potrebbe controllare l\'interfaccia utente del sistema senza l\'intervento dell\'utente."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"chiusura parziale"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Mette il gestore delle attività in uno stato di chiusura. Non esegue una chiusura completa."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedire commutazione applicazione"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 18db794..f5a7e81 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"מאפשר ליישום לאחזר את המצב הפנימי של המערכת. יישומים זדוניים עלולים לאחזר מגוון רחב של מידע אישי ונתוני אבטחה, שעל פי רוב לעולם לא יזדקקו להם."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"אחזר את תוכן המסך"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"מאפשר ליישום לאחזר את התוכן של החלון הפעיל. יישומים זדוניים עלולים לאחזר את תוכן החלון כולו ולבחון את כל הטקסט שבו, מלבד סיסמאות."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"אחזר מידע חלון"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"מאפשר ליישום לאחזר מידע לגבי החלונות ממנהל החלונות. יישומים זדוניים עשויים לאחזר מידע המיועד לשימוש מערכת פנימי."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"סנן אירועים"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"מאפשר ליישום לרשום מסנן קלט שמסנן את הזרם של כל אירועי המשתמש לפני שהם נשלחים. יישום זדוני עשוי לשלוט ב-UI של המערכת ללא התערבות משתמש."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"כיבוי חלקי"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"מעביר את מנהל הפעילויות למצב כיבוי. לא מבצע כיבוי מלא."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"מנע החלפת יישומים"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 238a9a8..048cd49 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"システムの内部状態の取得をアプリに許可します。この許可を悪意のあるアプリに利用されると、通常必要ないはずの各種の非公開/機密情報が取得される恐れがあります。"</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"画面のコンテンツの取得"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"作業中のウィンドウの内容を取得することをアプリに許可します。この許可を悪意のあるアプリに利用されると、ウィンドウの内容全体が取得されてパスワード以外のテキストがすべてチェックされる恐れがあります。"</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ウィンドウ情報の取得"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ウィンドウマネージャからウィンドウに関する情報を取得することをアプリに許可します。悪意のあるアプリが内部システムの利用を目的に情報を取得する恐れがあります。"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"イベントのフィルタリング"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"すべてのユーザーイベントが送られる前にストリームをフィルタリングする入力フィルタを登録することをアプリに許可します。悪意のあるアプリがユーザーの操作なしでシステムUIを制御する恐れがあります。"</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"部分的にシャットダウンする"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"アクティビティマネージャをシャットダウン状態にします。完全なシャットダウンは実行しません。"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"アプリケーションの切り替えを禁止する"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 178c202..fd24d2ab4 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Ļauj lietotnei izgūt sistēmas iekšējo statusu. Ļaunprātīgas lietotnes var izgūt dažādu privātu un drošu informāciju, kas parasti tām nav nepieciešama."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"Ekrāna satura iegūšana"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ļauj lietotnei izgūt aktīva loga saturu. Ļaunprātīgas lietotnes var izgūt visu loga saturu un pārbaudīt visu tā tekstu, izņemot paroles."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"Izgūt informāciju par logiem"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Ļauj lietojumprogrammai no logu pārvaldnieka izgūt informāciju par logiem. Ļaunprātīgas lietotnes var izgūt informāciju, kas ir paredzēta iekšējai izmantošanai sistēmā."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"Filtrēt notikumus"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Ļauj lietojumprogrammai reģistrēt ieejas filtru, kas filtrē visu lietotāja notikumu straumi, pirms notikumi tiek nosūtīti. Ļaunprātīga lietotne var kontrolēt sistēmas lietotāja saskarni, nejautājot lietotājam."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"daļēja izslēgšana"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Liek darbību pārvaldniekam pāriet izslēgšanas stāvoklī. Neveic pilnīgu izslēgšanu."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"novērst lietojumprogrammu pārslēgšanu"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a205ba8..92e4edc 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Lar appen hente ut informasjon om systemets indre tilstand. Ondsinnede apper kan hente et bredt spekter av privat og sikker informasjon som de vanligvis aldri burde ha behov for."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hent av skjerminnhold"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Lar appen hente ut innholdet i det aktive vinduet. Ondsinnede apper kan hente ut hele vindusinnholdet og undersøke all teksten, med unntak av passord."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hente vindusinformasjon"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Lar appen hente informasjon om vinduene fra vindusbehandleren. Skadelige apper kan hente informasjon som ikke er ment for intern systembruk."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrere hendelser"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Lar appen registrere et inndatafilter som filtrerer strømmen for alle brukerhendelser før de sendes ut. Skadelige apper kan kontrollere brukergrensesnittet for systemet uten at brukeren gjør noe."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"delvis avslutning"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Lar applikasjonen sette aktivitetshåndtereren i avslutningstilstand. Slår ikke systemet helt av."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"forhindre applikasjonsbytte"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b82f76e..c6c4d5f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Hiermee kan de app de interne systeemstatus ophalen. Schadelijke apps kunnen een grote hoeveelheid persoonlijke en beveiligde informatie ophalen die ze normaal gesproken nooit nodig hebben."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"scherminhoud ophalen"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Hiermee kan de app de inhoud van het actieve venster ophalen. Schadelijke apps kunnen de volledige inhoud van het venster ophalen en alle tekst bekijken, behalve wachtwoorden."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"venstergegevens ophalen"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Toestaan dat een app gegevens over vensters kan ophalen uit vensterbeheer. Schadelijke apps kunnen gegevens ophalen die zijn bedoeld voor interne systeemfunctionaliteit."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"evenementen filteren"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Toestaan dat een app een invoerfilter registreert waarmee de streams van alle gebruikersgebeurtenissen worden gefilterd voordat deze worden verzonden. Schadelijke apps kunnen de gebruikersinterface van het systeem beheren zonder tussenkomst van de gebruiker."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"gedeeltelijke uitschakeling"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Hiermee wordt activiteitenbeheer uitgeschakeld. Er wordt geen volledige uitschakeling uitgevoerd."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"schakelen tussen apps voorkomen"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 50163ba..cc5ece7 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Permite que a aplicação obtenha o estado interno do sistema. As aplicações maliciosas podem obter uma ampla variedade de dados privados e seguros de que, normalmente, nunca devem necessitar."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"obter o conteúdo do ecrã"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permite que a aplicação obtenha o conteúdo da janela ativa. As aplicações maliciosas podem obter todo o conteúdo da janela e examinar todo o texto, exceto as palavras-passe."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"obter informações da janela"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permite que uma aplicação obtenha informações sobre as janelas a partir do gestor de janelas. Aplicações maliciosas podem obter informações que se destinam à utilização interna do sistema."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrar eventos"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permite que uma aplicação registe um filtro de entrada que filtra a transmissão em fluxo contínuo para todos os eventos de utilizador antes de serem entregues. Uma aplicação maliciosa pode controlar a IU do sistema sem intervenção do utilizador."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"encerramento parcial"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Coloca o gestor de actividade num estado de encerramento. Não executa um encerramento completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir trocas de aplicações"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 63e270f..50d1a28 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -950,8 +950,8 @@
     <string name="no" msgid="5141531044935541497">"Zrušiť"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Pozor"</string>
     <string name="loading" msgid="7933681260296021180">"Prebieha načítavanie..."</string>
-    <string name="capital_on" msgid="1544682755514494298">"ZAPNUTÉ"</string>
-    <string name="capital_off" msgid="6815870386972805832">"VYPNUTÉ"</string>
+    <string name="capital_on" msgid="1544682755514494298">"I"</string>
+    <string name="capital_off" msgid="6815870386972805832">"O"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Dokončiť akciu pomocou aplikácie"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Použiť ako predvolené nastavenie pre túto akciu."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Vymazať predvolené nastavenia v sekcii Nastavenia systému &gt; Aplikácie &gt; Prevzaté položky."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index af58202..bdaa373 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Programu omogoča prejemanje notranjega stanja sistema. Zlonamerni programi lahko na ta način dobijo različne zasebne in varnostne podatke, ki jih običajno ne potrebujejo."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"prenos vsebine zaslona"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Programu omogoča dostop do vsebine aktivnega okna. Zlonamerni programi lahko dobijo vso vsebino okna in pregledajo njeno besedilo razen gesel."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"prenos podatkov o oknih"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Omogoča, da aplikacija iz upravitelja oken prenaša podatke o oknih. Zlonamerne aplikacije lahko prenašajo podatke, namenjene za notranjo uporabo v sistemu."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtriranje dogodkov"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Omogoča, da aplikacija registrira vhodni filter, ki pred razpošiljanjem filtrira tok vseh uporabniških dogodkov. Zlonamerne aplikacije lahko nadzirajo uporabniški vmesnik sistema brez posega uporabnika."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"delna zaustavitev"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Upravitelja dejavnosti preklopi v stanje za zaustavitev. Ne izvede celotne zaustavitve."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"preprečevanje preklopa programov"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 38206f1..31d63397 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Tillåter att appen hämtar systemets interna status. Skadliga appar kan hämta privat och skyddad information som normalt aldrig ska behövas."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hämta skärminnehåll"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tillåter att appen hämtar innehållet i det aktiva fönstret. Skadliga appar kan hämta allt innehåll i fönstret och läsa all text utom lösenord."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hämta information om fönster"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tillåter att appen hämtar information om fönstren från fönsterhanteraren. Skadliga appar kan hämta information som är avsedd för användning i det interna systemet."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrera händelser"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Tillåter att appen registrerar indatafilter som filtrerar flödet med användarhändelser innan de skickas. Skadliga appar kan styra systemets användargränssnitt utan att användaren gör något."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"avsluta delvis"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Sätter aktivitetshanteraren i avstängningsläge. Utför inte en fullständig avstängning."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"förhindrar programbyten"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b1d89b1..43e22da 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Inaruhusu programu kutoa hali ya ndani ya mfumo. Programu hasidi zinaweza kutoa aina nyingi za taarifa za faragha na salama ambazo kwa kawaida hazihitaji."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"epua maudhui ya skrini"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Inaruhusu programu kutoa maudhui ya dirisha amilifu. Programu hasidi zinaweza kutoa maudhui yote ya dirisha na kuchunguza maandishi yake yote isipokuwa nenosiri."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"okoa maelezo ya dirisha"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Huruhusu programu kuokoa maelezo kuhusu madirisha kutoka kwenye kidhibiti dirisha. Huenda programu hasidi ikaokoa maelezo ambayo yamekusudiwa kwa matumizi ya mfumo wa ndani."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"chuja matukio"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Huruhusu programu kusajili kichujio ingizo kinachochuja mkondo wa matukio ya mtumiaji kabla ya kutumwa. Huenda programu hasidi zikadhibiti mfumo wa UI bila mtumiaji kuingilia kati."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"Zima nusu"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Huweka kisimamia shughuli katika hali ya kuzima. Haiadhiri uzimaji kamili"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zuia swichi za app"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index dca6594..0fe2afe 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Дозволяє програмі отримувати дані про внутрішній стан системи. Шкідливі програми можуть отримувати значну кількість особистої та конфіденційної інформації, яка для них не призначена."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"отримувати вміст екрана"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Дозволяє програмі отримувати вміст активного вікна. Шкідливі програми можуть отримувати весь вміст вікна та вивчати весь його текст, окрім паролів."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"отримувати інформацію про вікна"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Дозволяє програмі отримувати інформацію про вікна від диспетчера вікон. Шкідливі програми можуть отримувати інформацію, яка призначена для внутрішнього користування системи."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"фільтрувати події"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Дозволяє програмі реєструвати вхідний фільтр, який фільтрує потік усіх подій користувача перед їх надсиланням. Шкідливі програми можуть контролювати інтерфейс системи без втручання користувача."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"частк. заверш. роб."</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Переводить диспетчер дій у стан завершення роботи. Не виконує повне завершення роботи."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"запобіг. зміні програм"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ffcfa06..59cdab1 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -243,14 +243,10 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Ivumela insiza ukuthi ithole kabusha ingaphakathi lesistimu. izinsiza ezinobungozi zingathola kabusha inqwaba yolwazi oluyimfihlo noluvikelekile ezingajwayele ukuthi ziludinge."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"letha okuqukethwe kwesikrini"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ivumela insiza ukuthi ithole okuqukethe kwi-Window. Izinsiza ezinobungozi zingathola kabush iwindi eliphelele bese ibheka konke okuqukethwe ngaphandle kwaaaphasiwedi."</string>
-    <!-- no translation found for permlab_retrieve_window_info (8532295199112519378) -->
-    <skip />
-    <!-- no translation found for permdesc_retrieve_window_info (4998836370424186849) -->
-    <skip />
-    <!-- no translation found for permlab_filter_events (8675535648807427389) -->
-    <skip />
-    <!-- no translation found for permdesc_filter_events (8006236315888347680) -->
-    <skip />
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"buyisa ulwazi lewindi"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Ivumela uhlelo lokusebenza ukubuyisa ulwazi mayelana namawindi avela kumphathi wewindi. Izinhlelo zokusebenza zingabuyisa ulwazi olubhekiswe ukusetshenziselwa kohlelo lwangaphakathi."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"hlunga izehlakalo"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Ivumela uhlelo lokusebenza ukubhalisa isihlungi sokufaka ukusakaza kwazo zonke izehlakalo zomsebenzisi ngaphambi kokuthunyelwa. Izinhlelo zokusebenza zingalawula i-UI yohlelo ngaphandle kokungena komsebenzisi."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"ukuvala shaqa kwengxenye"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Ibeka imeneja yomsebenzi kwisimo sokuvala shaqa. Ayenzi ukuvala shaqa okuphelele."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"gwema ukushintsha kohlelo lokusebenza"</string>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 4b93e74..38a75b6 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -42,6 +42,10 @@
         <group gid="net_bt" />
     </permission>
 
+    <permission name="android.permission.NET_TUNNELING" >
+        <group gid="vpn" />
+    </permission>
+
     <permission name="android.permission.INTERNET" >
         <group gid="inet" />
     </permission>
diff --git a/docs/html/about/versions/android-4.0.3.jd b/docs/html/about/versions/android-4.0.3.jd
index b7d4db3..a8c7e83 100644
--- a/docs/html/about/versions/android-4.0.3.jd
+++ b/docs/html/about/versions/android-4.0.3.jd
@@ -44,8 +44,7 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    <strong>Table of Contents</strong>
+class="toggle-content-img" alt="" /><strong>Table of Contents</strong>
   </a></p>
 
   <div class="toggle-content-toggleme" style="padding-left:2em;">
diff --git a/docs/html/design/patterns/actionbar.jd b/docs/html/design/patterns/actionbar.jd
index fe77e79..4206301 100644
--- a/docs/html/design/patterns/actionbar.jd
+++ b/docs/html/design/patterns/actionbar.jd
@@ -141,7 +141,9 @@
 </ul>
 <p>Use CABs whenever you allow the user to select data via long press. You can control the action
 content of a CAB in order to insert the actions you would like the user to be able to perform.</p>
-<p>For more information, refer to the "Selection" pattern.</p>
+<p>For more information, refer to the <a href="{@docRoot}design/patterns/selection.html">Selection
+pattern</a>.</p>
+
 <h2 id="elements">Action Bar Elements</h2>
 
 <h4>Tabs</h4>
diff --git a/docs/html/guide/google/gcm/adv.jd b/docs/html/guide/google/gcm/adv.jd
index aec8ca4..39e946e 100644
--- a/docs/html/guide/google/gcm/adv.jd
+++ b/docs/html/guide/google/gcm/adv.jd
@@ -27,6 +27,7 @@
   <ol>
     <li><a href="#s2s">Send-to-sync messages</a></li>
     <li><a href="#payload">Messages with payload</a></li>
+<li><a href="#which">Which should I use?</a></li>
     </ol>
 </li>
 <li><a href="#ttl">Setting an Expiration Date for a Message</a> </li>
@@ -185,10 +186,22 @@
 <p>Note that it might take a while for the registration ID be completely removed from GCM. Thus it is possible that messages sent during step 7 above gets a valid message ID as response, even though the message will not be delivered to the device. Eventually, the registration ID will be removed and the server will get a <code>NotRegistered</code> error, without any further action being required from the 3rd-party server (this scenario happens frequently while an application is being developed and tested).</p>
 
 <h2 id="collapsible">Send-to-Sync  vs. Messages with Payload</h2>
-<p>Every message sent in GCM, regardless of its other characteristics, is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with payload&quot; (non-collapsible message).</p>
+
+<p>Every message sent in GCM has the following characteristics:</p>
+<ul>
+  <li>It has a payload limit of 4096 bytes.</li>
+  <li>By default, it is stored by GCM for 4 weeks.</li>
+</ul>
+
+<p>But despite these similarities, messages can behave very differently depending on their particular settings. One major distinction between messages is whether they are collapsed (where each new message replaces the preceding message) or not collapsed (where each individual message is delivered). Every message sent in GCM is either a &quot;send-to-sync&quot; (collapsible) message or a &quot;message with payload&quot; (non-collapsible message). These concepts are described in more detail in the following sections.</p>
+
 <h3 id="s2s"><strong>Send-to-sync messages</strong></h3>
-<p>A send-to-sync (collapsible) message is typically a &quot;tickle&quot; that tells a mobile application to sync data from the server. For example, suppose you have an email application. When a user receives new email on the server, the server pings the mobile application with a &quot;New mail&quot; message. This tells the application to sync to the server to pick up the new email. The server might send this message multiple times as new mail continues to accumulate, before the application has had a chance to sync. But if the user has received 25 new emails, there's no need to preserve every &quot;New mail&quot; message. One  is sufficient. This is a case where you would use the GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the last message gets sent to the client. For example, &quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
-<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server at any given time. In other words, the GCM server can simultaneously store 4 different send-to-sync messages, each with a different collapse key.</p>
+
+<p>A send-to-sync (collapsible) message is often a &quot;tickle&quot; that tells a mobile application to sync data from the server. For example, suppose you have an email application. When a user receives new email on the server, the server pings the mobile application with a &quot;New mail&quot; message. This tells the application to sync to the server to pick up the new email. The server might send this message multiple times as new mail continues to accumulate, before the application has had a chance to sync. But if the user has received 25 new emails, there's no need to preserve every &quot;New mail&quot; message. One is sufficient. Another example would be a sports application that updates users with the latest score. Only the most recent message is relevant, so it makes sense to have each new message replace the preceding message. </p>
+
+<p>The email and sports applications are cases where you would probably use the GCM <code>collapse_key</code> parameter. A <em>collapse key</em> is an arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the most recent message gets sent to the client. For example, &quot;New mail,&quot; &quot;Updates available,&quot; and so on</p>
+<p>GCM allows a maximum of 4 different collapse keys to be used by the GCM server at any given time. In other words, the GCM server can simultaneously store 4 different send-to-sync messages, each with a different collapse key. If you exceed this number GCM will only keep 4 collapse keys, with no guarantees about which ones they will be.</p>
+
 <h3 id="payload">Messages with payload</h3>
 <p>Unlike a send-to-sync message, every &quot;message with payload&quot; (non-collapsible message) is delivered. The payload the message contains can be up to 4K. For example, here is a JSON-formatted message in an IM application in which spectators are discussing a sporting event:</p>
 
@@ -208,9 +221,10 @@
   <li><code>total_deleted</code>&mdash;The value  is a string with the number of deleted messages.</li>
 </ul>
 <p>The application should respond by syncing with the server to recover the discarded messages. </p>
-  <p class="note"><strong>Note:</strong> If your application does not need to use non-collapsible messages, collapsible messages are a better choice from a performance standpoint, because they put less of a burden on the device battery.
- 
-</p>
+
+<h3 id="which">Which should I use?</h3>
+  <p>If your application does not need to use non-collapsible messages, collapsible messages are a better choice from a performance standpoint, because they put less of a burden on the device battery.</p>
+
 <h2 dir="ltr" id="ttl">Setting an Expiration Date for a Message</h2>
 <p>The Time to Live (TTL) feature lets  the sender  specify the maximum lifespan of a message using the <code>time_to_live</code> parameter in the send request. The value of this parameter must be a duration from 0 to 2,419,200 seconds, and it corresponds to the maximum period of time for which GCM will store and try to deliver the message. Requests that don't contain this field default to the maximum period of 4 weeks.</p>
 <p>Here are some possible uses for this feature:</p>
diff --git a/docs/html/guide/google/gcm/client-javadoc/allclasses-frame.html b/docs/html/guide/google/gcm/client-javadoc/allclasses-frame.html
index 4788142..26916d5 100644
--- a/docs/html/guide/google/gcm/client-javadoc/allclasses-frame.html
+++ b/docs/html/guide/google/gcm/client-javadoc/allclasses-frame.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/client-javadoc/allclasses-noframe.html b/docs/html/guide/google/gcm/client-javadoc/allclasses-noframe.html
index cf3b68c..6ae9fe0 100644
--- a/docs/html/guide/google/gcm/client-javadoc/allclasses-noframe.html
+++ b/docs/html/guide/google/gcm/client-javadoc/allclasses-noframe.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBaseIntentService.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBaseIntentService.html
index 0b2cfad..eed1aea 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBaseIntentService.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBaseIntentService.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:36 PDT 2012 -->
 <TITLE>
 GCMBaseIntentService
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -107,6 +107,8 @@
  hence should run in a limited amount of time. If they execute long
  operations, they should spawn new threads, otherwise the worker thread will
  be blocked.
+ <p>
+ Subclasses must provide a public no-arg constructor.
 <P>
 
 <P>
@@ -142,11 +144,19 @@
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>protected </CODE></FONT></TD>
-<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService(java.lang.String)">GCMBaseIntentService</A></B>(java.lang.String&nbsp;senderId)</CODE>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService()">GCMBaseIntentService</A></B>()</CODE>
 
 <BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Subclasses must create a public no-arg constructor and pass the
- sender id to be used for registration.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor that does not set a sender id, useful when the sender id
+ is context-specific.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected </CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService(java.lang.String...)">GCMBaseIntentService</A></B>(java.lang.String...&nbsp;senderIds)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Constructor used when the sender id(s) is fixed.</TD>
 </TR>
 </TABLE>
 &nbsp;
@@ -160,6 +170,14 @@
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.String[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#getSenderIds(Context)">getSenderIds</A></B>(Context&nbsp;context)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the sender ids.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>protected &nbsp;void</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#onDeletedMessages(Context, int)">onDeletedMessages</A></B>(Context&nbsp;context,
                   int&nbsp;total)</CODE>
@@ -263,13 +281,28 @@
 </TR>
 </TABLE>
 
-<A NAME="GCMBaseIntentService(java.lang.String)"><!-- --></A><H3>
+<A NAME="GCMBaseIntentService()"><!-- --></A><H3>
 GCMBaseIntentService</H3>
 <PRE>
-protected <B>GCMBaseIntentService</B>(java.lang.String&nbsp;senderId)</PRE>
+protected <B>GCMBaseIntentService</B>()</PRE>
 <DL>
-<DD>Subclasses must create a public no-arg constructor and pass the
- sender id to be used for registration.
+<DD>Constructor that does not set a sender id, useful when the sender id
+ is context-specific.
+ <p>
+ When using this constructor, the subclass <strong>must</strong>
+ override <A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#getSenderIds(Context)"><CODE>getSenderIds(Context)</CODE></A>, otherwise methods such as
+ <A HREF="../../../../com/google/android/gcm/GCMBaseIntentService.html#onHandleIntent(Intent)"><CODE>onHandleIntent(Intent)</CODE></A> will throw an
+ <CODE>IllegalStateException</CODE> on runtime.
+<P>
+</DL>
+<HR>
+
+<A NAME="GCMBaseIntentService(java.lang.String...)"><!-- --></A><H3>
+GCMBaseIntentService</H3>
+<PRE>
+protected <B>GCMBaseIntentService</B>(java.lang.String...&nbsp;senderIds)</PRE>
+<DL>
+<DD>Constructor used when the sender id(s) is fixed.
 <P>
 </DL>
 
@@ -283,6 +316,24 @@
 </TR>
 </TABLE>
 
+<A NAME="getSenderIds(Context)"><!-- --></A><H3>
+getSenderIds</H3>
+<PRE>
+protected java.lang.String[] <B>getSenderIds</B>(Context&nbsp;context)</PRE>
+<DL>
+<DD>Gets the sender ids.
+
+ <p>By default, it returns the sender ids passed in the constructor, but
+ it could be overridden to provide a dynamic sender id.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if sender id was not set on constructor.</DL>
+</DD>
+</DL>
+<HR>
+
 <A NAME="onMessage(Context, Intent)"><!-- --></A><H3>
 onMessage</H3>
 <PRE>
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBroadcastReceiver.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBroadcastReceiver.html
index f0b3e26..2a1c676 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBroadcastReceiver.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBroadcastReceiver.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:36 PDT 2012 -->
 <TITLE>
 GCMBroadcastReceiver
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMConstants.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMConstants.html
index feb2225..f778f06 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMConstants.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMConstants.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:36 PDT 2012 -->
 <TITLE>
 GCMConstants
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html
index a933bc6..bb486ff 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMRegistrar.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:36 PDT 2012 -->
 <TITLE>
 GCMRegistrar
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -74,9 +74,9 @@
 </TR>
 <TR>
 <TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
 <TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
 </TR>
 </TABLE>
 <A NAME="skip-navbar_top"></A>
@@ -109,7 +109,25 @@
 <HR>
 
 <P>
+<!-- =========== FIELD SUMMARY =========== -->
 
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#DEFAULT_ON_SERVER_LIFESPAN_MS">DEFAULT_ON_SERVER_LIFESPAN_MS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Default lifespan (7 days) of the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegisteredOnServer(Context)"><CODE>isRegisteredOnServer(Context)</CODE></A>
+ flag until it is considered expired.</TD>
+</TR>
+</TABLE>
+&nbsp;
 <!-- ========== METHOD SUMMARY =========== -->
 
 <A NAME="method_summary"><!-- --></A>
@@ -136,6 +154,15 @@
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;long</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#getRegisterOnServerLifespan(Context)">getRegisterOnServerLifespan</A></B>(Context&nbsp;context)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets how long (in milliseconds) the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ property is valid.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#getRegistrationId(Context)">getRegistrationId</A></B>(Context&nbsp;context)</CODE>
 
@@ -157,7 +184,8 @@
 <TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegisteredOnServer(Context)">isRegisteredOnServer</A></B>(Context&nbsp;context)</CODE>
 
 <BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Checks whether the device was successfully registered in the server side.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Checks whether the device was successfully registered in the server side,
+ as set by <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#setRegisteredOnServer(Context, boolean)"><CODE>setRegisteredOnServer(Context, boolean)</CODE></A>.</TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -188,6 +216,16 @@
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#setRegisterOnServerLifespan(Context, long)">setRegisterOnServerLifespan</A></B>(Context&nbsp;context,
+                            long&nbsp;lifespan)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets how long (in milliseconds) the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ flag is valid.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#unregister(Context)">unregister</A></B>(Context&nbsp;context)</CODE>
 
 <BR>
@@ -206,6 +244,28 @@
 &nbsp;
 <P>
 
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="DEFAULT_ON_SERVER_LIFESPAN_MS"><!-- --></A><H3>
+DEFAULT_ON_SERVER_LIFESPAN_MS</H3>
+<PRE>
+public static final long <B>DEFAULT_ON_SERVER_LIFESPAN_MS</B></PRE>
+<DL>
+<DD>Default lifespan (7 days) of the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegisteredOnServer(Context)"><CODE>isRegisteredOnServer(Context)</CODE></A>
+ flag until it is considered expired.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../constant-values.html#com.google.android.gcm.GCMRegistrar.DEFAULT_ON_SERVER_LIFESPAN_MS">Constant Field Values</A></DL>
+</DL>
+
 <!-- ============ METHOD DETAIL ========== -->
 
 <A NAME="method_detail"><!-- --></A>
@@ -375,7 +435,44 @@
 <PRE>
 public static boolean <B>isRegisteredOnServer</B>(Context&nbsp;context)</PRE>
 <DL>
-<DD>Checks whether the device was successfully registered in the server side.
+<DD>Checks whether the device was successfully registered in the server side,
+ as set by <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#setRegisteredOnServer(Context, boolean)"><CODE>setRegisteredOnServer(Context, boolean)</CODE></A>.
+
+ <p>To avoid the scenario where the device sends the registration to the
+ server but the server loses it, this flag has an expiration date, which
+ is <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#DEFAULT_ON_SERVER_LIFESPAN_MS"><CODE>DEFAULT_ON_SERVER_LIFESPAN_MS</CODE></A> by default (but can be changed
+ by <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#setRegisterOnServerLifespan(Context, long)"><CODE>setRegisterOnServerLifespan(Context, long)</CODE></A>).
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRegisterOnServerLifespan(Context)"><!-- --></A><H3>
+getRegisterOnServerLifespan</H3>
+<PRE>
+public static long <B>getRegisterOnServerLifespan</B>(Context&nbsp;context)</PRE>
+<DL>
+<DD>Gets how long (in milliseconds) the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ property is valid.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>value set by <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#setRegisteredOnServer(Context, boolean)"><CODE>setRegisteredOnServer(Context, boolean)</CODE></A> or
+      <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#DEFAULT_ON_SERVER_LIFESPAN_MS"><CODE>DEFAULT_ON_SERVER_LIFESPAN_MS</CODE></A> if not set.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setRegisterOnServerLifespan(Context, long)"><!-- --></A><H3>
+setRegisterOnServerLifespan</H3>
+<PRE>
+public static void <B>setRegisterOnServerLifespan</B>(Context&nbsp;context,
+                                               long&nbsp;lifespan)</PRE>
+<DL>
+<DD>Sets how long (in milliseconds) the <A HREF="../../../../com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ flag is valid.
 <P>
 <DD><DL>
 </DL>
@@ -431,9 +528,9 @@
 </TR>
 <TR>
 <TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
 <TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
-DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
 </TR>
 </TABLE>
 <A NAME="skip-navbar_bottom"></A>
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-frame.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-frame.html
index 9dc665f..4828eea 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-frame.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-frame.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 com.google.android.gcm
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-summary.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-summary.html
index 2b15b81..877248b 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-summary.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-summary.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 com.google.android.gcm
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-tree.html b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-tree.html
index f36a8a69..bf6fce3 100644
--- a/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-tree.html
+++ b/docs/html/guide/google/gcm/client-javadoc/com/google/android/gcm/package-tree.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 com.google.android.gcm Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/constant-values.html b/docs/html/guide/google/gcm/client-javadoc/constant-values.html
index 171c6a1..6ccd123 100644
--- a/docs/html/guide/google/gcm/client-javadoc/constant-values.html
+++ b/docs/html/guide/google/gcm/client-javadoc/constant-values.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 Constant Field Values
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -251,6 +251,24 @@
 <P>
 
 <P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">com.google.android.gcm.<A HREF="com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="com.google.android.gcm.GCMRegistrar.DEFAULT_ON_SERVER_LIFESPAN_MS"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;long</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="com/google/android/gcm/GCMRegistrar.html#DEFAULT_ON_SERVER_LIFESPAN_MS">DEFAULT_ON_SERVER_LIFESPAN_MS</A></CODE></TD>
+<TD ALIGN="right"><CODE>604800000L</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
 <HR>
 
 
diff --git a/docs/html/guide/google/gcm/client-javadoc/default.css b/docs/html/guide/google/gcm/client-javadoc/default.css
new file mode 100644
index 0000000..2513e69
--- /dev/null
+++ b/docs/html/guide/google/gcm/client-javadoc/default.css
@@ -0,0 +1,4005 @@
+/* color definitions */
+/* 16 column layout */
+/* clearfix idiom */
+/* common mixins */
+/* page layout + top-level styles */
+::-webkit-selection,
+::-moz-selection,
+::selection {
+  background-color: #0099cc;
+  color: #fff; }
+
+html, body {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  background-color:#F9F9F9;
+  -webkit-font-smoothing: antialiased;
+  /* prevent subpixel antialiasing, which thickens the text */
+  /* text-rendering: optimizeLegibility; */
+  /* turned off ligatures due to bug 5945455 */ }
+
+body {
+  color: #222;
+  font: 14px/19px Roboto, sans-serif;
+  font-weight: 400;
+  letter-spacing:.1;
+  padding:0 10px; }
+
+#page-container {
+  width: 940px;
+  margin: 0 40px; }
+
+#page-header {
+  height: 80px;
+  margin-bottom: 20px;
+  font-size: 48px;
+  line-height: 48px;
+  font-weight: 100;
+  padding-left: 10px; }
+  #page-header a {
+    display: block;
+    position: relative;
+    top: 20px;
+    text-decoration: none;
+    color: #555555 !important; }
+
+#main-row {
+  display: inline-block; }
+  #main-row:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden; }
+  * html #main-row {
+    height: 1px; }
+
+#page-footer {
+  margin-left: 190px;
+  margin-top: 80px;
+  color: #999999;
+  padding-bottom: 40px;
+  font-size: 12px;
+  line-height: 15px; }
+  #page-footer a {
+    color: #777777; }
+  #page-footer #copyright {
+    margin-bottom: 10px; }
+
+#nav-container {
+  width: 160px;
+  min-height: 10px;
+  margin-right: 20px;
+  float: left; }
+
+#nav {
+  margin:0;
+  padding:0 0 30px;
+}
+
+#side-nav {
+  min-height:5px; /* silly way to avoid doc floating left when nav goes fixed */
+  margin-bottom:1px;
+}
+#devdoc-nav {
+  outline:none;
+  width:auto;
+  margin: 20px 0 0; }
+  
+#devdoc-nav h2 {
+  border:0;
+}
+
+#devdoc-nav.fixed {
+  position: fixed;
+  margin:0;
+  top: 20px; }
+
+#content {
+  width: 760px;
+  float: left; }
+
+a:hover,
+acronym:hover {
+  color: #7aa1b0 !important; }
+
+a:focus,
+a:active {
+  color: #33b5e5 !important; }
+
+img {
+  border: none; }
+#jd-content img {
+  margin-bottom:15px;
+}
+
+ul {
+  margin: 0;
+  padding: 0; }
+
+strong {
+  font-weight: 500; }
+
+em {
+  font-style: italic; }
+
+acronym {
+  border-bottom: 1px dotted #555555;
+  cursor: help; }
+
+acronym:hover {
+  border-bottom-color: #7aa1b0; }
+
+img.with-shadow,
+video.with-shadow {
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25); }
+
+/* disclosures mixin */
+/* content layout */
+.layout-content-row {
+  display: inline-block;
+  margin-bottom: 10px; }
+  .layout-content-row:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden; }
+  * html .layout-content-row {
+    height: 1px; }
+
+.layout-content-col {
+  float: left;
+  margin-left: 20px; }
+  .layout-content-col:first-child {
+    margin-left: 0; }
+  .layout-content-col h3,
+  .layout-content-col h4 {
+    margin-top:0; }
+
+.layout-content-col.span-1 {
+  width: 40px; }
+
+.layout-content-col.span-2 {
+  width: 100px; }
+
+.layout-content-col.span-3 {
+  width: 160px; }
+
+.layout-content-col.span-4 {
+  width: 220px; }
+
+.layout-content-col.span-5 {
+  width: 280px; }
+
+.layout-content-col.span-6 {
+  width: 340px; }
+
+.layout-content-col.span-7 {
+  width: 400px; }
+
+.layout-content-col.span-8 {
+  width: 460px; }
+
+.layout-content-col.span-9 {
+  width: 520px; }
+
+.layout-content-col.span-10 {
+  width: 580px; }
+
+.layout-content-col.span-11 {
+  width: 640px; }
+
+.layout-content-col.span-12 {
+  width: 700px; }
+
+.layout-content-col.span-13 {
+  width: 760px; }
+
+.vspace.size-1 {
+  height: 10px; }
+
+.vspace.size-2 {
+  height: 20px; }
+
+.vspace.size-3 {
+  height: 30px; }
+
+.vspace.size-4 {
+  height: 40px; }
+
+.vspace.size-5 {
+  height: 50px; }
+
+.vspace.size-6 {
+  height: 60px; }
+
+.vspace.size-7 {
+  height: 70px; }
+
+.vspace.size-8 {
+  height: 80px; }
+
+.vspace.size-9 {
+  height: 90px; }
+
+.vspace.size-10 {
+  height: 100px; }
+
+.vspace.size-11 {
+  height: 110px; }
+
+.vspace.size-12 {
+  height: 120px; }
+
+.vspace.size-13 {
+  height: 130px; }
+
+.vspace.size-14 {
+  height: 140px; }
+
+.vspace.size-15 {
+  height: 150px; }
+
+.vspace.size-16 {
+  height: 160px; }
+
+/* nav */
+#nav {
+  /* section header divs */
+  /* expanded section header divs */
+  /* sublinks */ }
+  #nav li {
+    list-style-type: none;
+    font-size: 14px;
+    margin:0;
+    padding:0;
+    line-height: 15px; }
+  #nav a {
+    color: #555555;
+    text-decoration: none; }
+  #nav .nav-section-header {
+    position: relative;
+    margin-bottom: 1px;
+    padding: 0 30px 0 0; }
+  #nav li.selected a, #nav li.selected > .nav-section-header > a {
+    color: #09C;
+  }
+  #nav li.selected ul li a {
+  /* don't highlight child items */
+    color: #555555; }
+  #nav .nav-section .nav-section .nav-section-header {
+    /* no white line between second level sections */
+    margin-bottom: 0; }
+    /* section header links */
+    #nav > li > div > a {
+      display: block;
+      color: #333333;
+      font-weight: 500;
+      padding: 10px 0 10px 10px; }
+    #nav .nav-section-header:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_down.png) no-repeat scroll 50% 50%;
+      width: 34px;
+      height: 34px;
+      display: block;
+      position: absolute;
+      top: 0;
+      right: 0; }
+    #nav .nav-section-header.empty:after {
+      display: none; }
+    /* nested nav headers */
+    #nav .nav-section .nav-section {
+      position: relative;
+      padding: 0;
+      margin: 0; }
+    #nav .nav-section li a {
+    /* first gen child (2nd level li) */
+      display:block;
+      font-weight: normal;
+      text-transform: none;
+      padding: 7px 5px 7px 10px;
+       }
+    #nav .nav-section li li a {
+    /* second gen child (3rd level li) */
+      padding: 5px 5px 5px 10px;
+       }
+  #nav li.expanded .nav-section-header {
+    background:#e9e9e9;
+    background: rgba(0, 0, 0, 0.05); }
+  #nav li.expanded li .nav-section-header {
+    background: transparent; }
+  #nav li.expanded li ul {
+  /* 3rd level ul */
+    padding:0 10px;
+  }
+    #nav li.expanded > .nav-section-header:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_up.png) no-repeat scroll 50% 50%;
+      width: 34px;
+      height: 34px; }
+  #nav li ul {
+    display:none;
+    overflow: hidden;
+    margin: 0; }
+    #nav li ul.animate-height-in {
+      -webkit-transition: height 0.25s ease-in;
+      -moz-transition: height 0.25s ease-in;
+      transition: height 0.25s ease-in; }
+    #nav li ul.animate-height-out {
+      -webkit-transition: height 0.25s ease-out;
+      -moz-transition: height 0.25s ease-out;
+      transition: height 0.25s ease-out; }
+    #nav li ul li {
+      padding: 0; }
+      #nav li li li {
+        padding: 0; }
+  #nav li.expanded ul {
+    }
+    #nav li ul > li {
+      padding:0;
+    }
+    #nav li ul > li:last-child {
+      padding-bottom:5px;
+    }
+    #nav li.expanded ul > li {
+      background:#efefef;
+      background: rgba(0, 0, 0, 0.03); }
+    #nav li.expanded ul > li li {
+      background:inherit; }
+
+.new,
+.new-child {
+  font-size: .78em;
+  font-weight: bold;
+  color: #ff3d3d;
+  vertical-align:top;
+  white-space:nowrap;
+}
+
+/* content header */
+.content-header {
+  height: 30px;
+  margin:20px 0 25px;
+  padding:0 0 10px;}
+.content-header.just-links {
+  margin-bottom:0;
+  padding-bottom:0;}
+    
+.content-header h1 {
+  color:#000;
+  margin:0;
+  border-bottom:0;
+  padding:0;
+}
+
+.content-footer {
+  border-top: 1px solid #ccc;
+  margin-top: 10px;
+  padding-top:10px;
+  height: 30px; }
+
+.content-footer .col-9 {
+  margin-left:0;
+}
+.content-footer .col-4 {
+  margin-right:0;
+}
+.content-footer.wrap {
+  width:940px;
+}
+
+.paging-links {
+  position: relative; }
+  .paging-links a {
+    position: absolute; }
+  .paging-links a,
+  .training-nav-top a {
+    font-size: 14px;
+    line-height: 30px;
+    color: #555555;
+    text-decoration: none;
+    text-transform: uppercase; }
+  .paging-links .prev-page-link,
+  .training-nav-top .prev-page-link {
+    left: -5px; }
+    .paging-links .prev-page-link:before,
+    .training-nav-top .prev-page-link:before {
+      content: '';
+      background: transparent url(../images/styles/disclosure_left.png) no-repeat scroll 50% 50%;
+      width: 10px;
+      height: 10px;
+      display: inline-block;
+      margin-right: 5px; }
+  .paging-links .next-page-link,
+  .training-nav-top .next-page-link,
+    .training-nav-top .start-class-link,
+    .training-nav-top .start-course-link {
+    right: 10px; }
+    .next-page-link:after,
+    .start-class-link:after,
+    .start-course-link:after,
+    .next-class-link:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_right.png) no-repeat scroll 50% 50%;
+      width: 10px;
+      height: 10px;
+      display: inline-block;
+      margin-left: 5px; }
+      
+      
+  .training-nav-top a {
+    display:block;
+    float:left;
+    width:108px;
+    height:28px;
+    padding: 8px 15px;
+    line-height:28px;
+    text-align:center;
+    border:1px solid #DADADA;
+    border-bottom:0;
+  }
+      
+  .training-nav-top a.next-page-link {
+    border-left:0;
+    width:109px;
+  }
+      
+  .training-nav-top a.disabled,
+  .content-footer a.disabled {
+    color:#999;
+  }
+      
+  .training-nav-top a.disabled:hover,
+  .content-footer a.disabled:hover {
+    cursor:default;
+    color:#999 !important;
+  }
+      
+  .training-nav-top a.start-class-link,
+  .training-nav-top a.start-course-link {
+    width:248px;
+  }
+  
+  .hide {
+    display:none !important;
+  }
+  
+  .content-footer.next-class {
+    display:block;
+    border:0;
+    margin-top:0;
+    padding-top:0;
+  }
+  
+  .content-footer.next-class a.next-class-link {
+    display:block;
+    float:right;
+    text-transform:uppercase;
+  }
+
+/* content body */
+@-webkit-keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+@-moz-keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+@keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+h2:target,
+h3:target {
+    -webkit-animation-name: glowheader;
+    -moz-animation-name: glowheader;
+    animation-name: glowheader;
+    -webkit-animation-duration: 0.7s;
+    -moz-animation-duration: 0.7s;
+    animation-duration: 0.7s;
+    -webkit-animation-timing-function: ease-out;
+    -moz-animation-timing-function: ease-out;
+    animation-timing-function: ease-out; }
+
+.design ol h4 {
+  margin-bottom:0;
+}
+.design ol {
+  counter-reset: item; }
+  .design ol li {
+    font-size: 14px;
+    line-height: 20px;
+    list-style-type: none;
+    position: relative; }
+    .design ol li:before {
+      content: counter(item) ". ";
+      counter-increment: item;
+      position: absolute;
+      left: -20px;
+      top: 0; }
+    .design ol li.value-1:before {
+      content: "1. "; }
+    .design ol li.value-2:before {
+      content: "2. "; }
+    .design ol li.value-3:before {
+      content: "3. "; }
+    .design ol li.value-4:before {
+      content: "4. "; }
+    .design ol li.value-5:before {
+      content: "5. "; }
+    .design ol li.value-6:before {
+      content: "6. "; }
+    .design ol li.value-7:before {
+      content: "7. "; }
+    .design ol li.value-8:before {
+      content: "8. "; }
+    .design ol li.value-9:before {
+      content: "9. "; }
+    .design ol li.value-10:before {
+      content: "10. "; }
+.design .with-callouts ol li {
+  list-style-position: inside;
+  margin-left: 0; }
+  .design .with-callouts ol li:before {
+    display: inline;
+    left: -20px;
+    float: left;
+    width: 17px;
+    color: #33b5e5;
+    font-weight: 500; }
+
+/* special list items */
+li.no-bullet {
+  list-style-type: none !important; }
+li.no-bullet *{
+  margin:0; }
+
+.design li.with-icon {
+  position: relative;
+  margin-left: 20px;
+  min-height: 30px; }
+  .design li.with-icon p {
+    margin-left: 0 !important; }
+  .design li.with-icon:before {
+    position: absolute;
+    left: -40px;
+    top: 0;
+    content: '';
+    width: 30px;
+    height: 30px; }
+  .design li.with-icon.tablet:before {
+    background-image: url(../images/styles/ico_phone_tablet.png); }
+  .design li.with-icon.web:before {
+    background-image: url(../images/styles/ico_web.png); }
+  .design li.with-icon.action:before {
+    background-image: url(../images/styles/ico_action.png); }
+  .design li.with-icon.use:before {
+    background-image: url(../images/styles/ico_use.png); }
+
+/* figures and callouts */
+.figure {
+  position: relative; }
+  .figure.pad-below {
+    margin-bottom: 20px; }
+  .figure .figure-callout {
+    position: absolute;
+    color: #fff;
+    font-weight: 500;
+    font-size: 16px;
+    line-height: 23px;
+    text-align: center;
+    background: transparent url(../images/styles/callout.png) no-repeat scroll 50% 50%;
+    padding-right: 2px;
+    width: 30px;
+    height: 29px;
+    z-index: 1000; }
+    .figure .figure-callout.top {
+      top: -9px; }
+    .figure .figure-callout.right {
+      right: -5px; }
+
+.figure-caption {
+  margin: 0 10px 20px 0;
+  font-size: 14px;
+  line-height: 20px;
+  font-style: italic; }
+
+/* rows of figures */
+.figure-row {
+  font-size: 0;
+  line-height: 0;
+  /* to prevent space between figures */ }
+  .figure-row .figure {
+    display: inline-block;
+    vertical-align: top; }
+  .figure-row .figure + .figure {
+    margin-left: 10px;
+    /* reintroduce space between figures */ }
+
+/* video  containers */
+.framed-galaxynexus-land-span-13 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_land_span13.png) no-repeat
+scroll top left;
+  padding: 42px 122px 62px 126px;
+  overflow: hidden; }
+  .framed-galaxynexus-land-span-13, .framed-galaxynexus-land-span-13 video,
+.framed-galaxynexus-land-span-13 img {
+    width: 512px;
+    height: 286px; }
+
+.framed-galaxynexus-port-span-9 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_port_span9.png) no-repeat
+scroll top left;
+  padding: 95px 122px 107px 124px;
+  overflow: hidden; }
+  .framed-galaxynexus-port-span-9, .framed-galaxynexus-port-span-9 video,
+.framed-galaxynexus-port-span-9 img {
+    width: 274px;
+    height: 488px; }
+
+.framed-galaxynexus-port-span-5 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_port_span5.png) no-repeat
+scroll top left;
+  padding: 75px 31px 76px 33px;
+  overflow: hidden; }
+  .framed-galaxynexus-port-span-5, .framed-galaxynexus-port-span-5 video,
+.framed-galaxynexus-port-span-5 img {
+    width: 216px;
+    height: 384px; }
+
+/* landing page disclosures */
+.landing-page-link {
+  text-decoration: none;
+  font-weight: 500;
+  color: #333333; }
+  .landing-page-link:after {
+    content: '';
+    background: transparent url(../images/styles/disclosure_right.png) no-repeat scroll 50% 50%;
+    width: 10px;
+    height: 10px;
+    display: inline-block;
+    margin-left: 5px; }
+
+/* tooltips */
+.tooltip-box {
+  position: absolute;
+  background-color: rgba(0, 0, 0, 0.9);
+  border-radius: 2px;
+  font-size: 14px;
+  line-height: 20px;
+  color: #fff;
+  padding: 6px 10px;
+  max-width: 250px;
+  z-index: 10000; }
+  .tooltip-box.below:after {
+    position: absolute;
+    content: '';
+    line-height: 0;
+    display: block;
+    top: -10px;
+    left: 5px;
+    border: 5px solid transparent;
+    border-bottom-color: rgba(0, 0, 0, 0.9); }
+
+/* video note */
+.video-instructions {
+  margin-top: 10px;
+  margin-bottom: 10px; }
+  .video-instructions:before {
+    content: '';
+    background: transparent url(../images/styles/ico_movie_inline.png) no-repeat scroll top left;
+    display: inline-block;
+    width: 12px;
+    height: 12px;
+    margin-right: 8px; }
+  .video-instructions:after {
+    content: 'Click device screen to replay movie.'; }
+
+/* download buttons */
+.download-button {
+  display: block;
+  margin-bottom: 5px;
+  text-decoration: none;
+  background-color: #33b5e5;
+  color: #fff !important;
+  font-weight: 500;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);
+  padding: 6px 12px;
+  border-radius: 2px; }
+  .download-button:hover, .download-button:focus {
+    background-color: #0099cc;
+    color: #fff !important; }
+  .download-button:active {
+    background-color: #006699; }
+
+/* UI tables and other things found in Writing style and Settings pattern */
+.ui-table {
+  width: 100%;
+  background-color: #282828;
+  color: #fff;
+  border-radius: 2px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
+  border-collapse: separate; }
+  .ui-table th,
+  .ui-table td {
+    padding: 5px 10px;
+    background-color: inherit; 
+    border:0;}
+  .ui-table thead th {
+    font-weight: bold; }
+  .ui-table tfoot td {
+    border-top: 1px solid #494949;
+    border-right: 1px solid #494949;
+    text-align: center; }
+    .ui-table tfoot td:last-child {
+      border-right: 0; }
+
+.layout-with-list-item-margins {
+  margin-left: 30px !important; }
+
+.emulate-content-left-padding {
+  margin-left: 10px; }
+
+.do-dont-label {
+  margin-bottom: 10px;
+  padding-left: 20px;
+  background: transparent none no-repeat scroll 0px 3px; }
+  .do-dont-label.bad {
+    background-image: url(../images/styles/ico_wrong.png); }
+  .do-dont-label.good {
+    background-image: url(../images/styles/ico_good.png); }
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***** PREVIOUSLY style.css ******************/
+
+
+
+
+
+@media screen, projection, print {
+[dir='rtl'] {
+    direction: rtl;
+}
+html {
+    line-height: 20px;
+}
+pre, table, input, textarea, code {
+    font-size: 1em;
+}
+address, abbr, cite {
+    font-style: normal;
+}
+[dir='rtl'] th {
+    text-align: right;
+}
+html[lang^=ja] blockquote, html[lang^=ja] q, html[lang^=ko] blockquote, html[lang^=ko] q,
+html[lang^=zh] blockquote, html[lang^=zh] q {
+    font-style: normal;
+}
+q {
+    font-style: italic;
+}
+fieldset, iframe, img {
+    border: 0;
+}
+img { 
+	-ms-interpolation-mode: bicubic;
+	vertical-align: middle;
+	max-width: 100%;
+}
+q {
+    quotes: none;
+}
+sup, sub {
+    font-size: 11px;
+    line-height: 0;
+}
+}
+
+@media screen, projection {
+
+table, fieldset {
+    margin: 0;
+}
+h1 {
+    color:#333;
+    font-size: 22px;
+    margin: 20px 0 20px;
+    padding:0 0 10px;
+}
+h1, h2 {
+    line-height: 32px;
+}
+h1.short {
+  margin-right:320px;
+}
+h1.short {
+  margin-right:320px;
+}
+h1.super {
+    font-size: 37px;	
+}
+h2 {
+    color:#333;
+    font-size: 20px;
+    margin: 20px 0 20px;
+    padding:0;
+}
+h3 {
+    color:#333;
+    font-size: 18px;
+}
+h3, h4 {
+    color:#333;
+    line-height: 20px;
+    margin: 10px 0;
+}
+h4 {
+	font-size: 16px;
+}
+h5 {
+	font-size: 14px;	
+}
+h5, h6 {
+	margin: 5px 0;
+}
+h6 {
+	font-size: 12px;	
+}
+hr { /* applied to the bottom of h2 elements */
+	height: 1px;
+	margin: 5px 0 20px;
+	border: 0;
+	background: #ccc;
+}
+p, pre, table, form {
+    margin: 0 0 15px;
+}
+small {
+	font-size: 11.5px;
+	color: #000;
+}
+ul, ol {
+    margin: 0 0 15px 18px;
+    padding: 0;
+}
+[dir='rtl'] ul, [dir='rtl'] ol {
+    margin: 10px 30px 10px 10px;
+}
+ul ul, ul ol, ol ul, ol ol {
+    margin-bottom: 0;
+    margin-top: 0;
+}
+li {
+  margin:0 0 4px;
+}
+dd {
+  margin:0 0 10px 30px;
+}
+dd p {
+  margin:10px 0 0;
+}
+ul p,
+ol p {
+  margin:10px 0 0;
+}
+pre strong, pre b, a strong, a b, a code {
+    color: inherit;
+}
+pre, code {
+    color: #060;
+    font: 14px/1.5 'courier new', courier, monospace;
+}
+code {
+    font-weight:bold;
+}
+
+legend {
+    display: none;
+}
+a:link, a:visited {
+  color: #258aaf;
+  text-decoration: none;
+}
+a:focus, a:hover, a:active {
+  color: #33B5E5;
+  text-decoration: none;
+}
+strong, b {
+  font-weight:bold;
+  color: #222;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+  border:0;
+  margin: .5em 1em 1em 0;
+  width:100%; /* consistent table widths; within IE's quirks */
+  background-color:#f7f7f7;
+}
+th, td {
+  padding: 4px 12px;
+  vertical-align: top;
+  text-align: left;
+}
+td {
+  background-color:inherit;
+  border:solid 1px #DDD;
+}
+th {
+  background-color: #999;
+  color: #fff;
+  border:solid 1px #DDD;
+  font-weight: normal;
+}
+tr:first-of-type th:first-of-type:empty {
+    visibility: hidden;
+}
+/* --------------------------------------------------------------------------
+Footer
+*/
+.line {
+    clear: both;
+    background: #acbc00;
+    background: -moz-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #acbc00),
+color-stop(50%, #acbc00), color-stop(50%, #bdde00), color-stop(100%, #bdde00));
+    background: -webkit-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -o-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -ms-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    height: 2px;
+    margin-top: 150px;
+    position: relative;
+    z-index: 11;
+}
+#footer {
+    font-size:11px;
+    clear: both;
+    color: #999;
+    padding: 15px 0;
+    margin-top:10px;
+    width:auto;
+}
+#footer-local ul {
+	list-style: none;
+	margin: 5px 0 30px 0;
+}
+#footer-local li {
+    display: inline;
+}
+#footer-local li+li:before {
+    content: '|';
+    padding: 0 3px;
+	color: #e5e5e5;
+}
+#footer-global {
+    padding: 10px 15px;
+	background: #f5f5f5;
+}
+#footer-global {
+    border-top: 1px solid #ebebeb;
+    font-size: 11.5px;
+    line-height: 1.8;
+    list-style: none;
+}
+#footer-global ul {
+    margin: 0;
+}
+#footer-global li {
+    display: inline;
+    font-weight: bold;
+}
+#footer-global li+li:before {
+    content: '¬?';
+    padding: 0 3px;
+}
+* html #footer-global li {
+    margin: 0 13px 0 0;
+}
+* [dir='rtl'] #footer-global li {
+    margin: 0 0 0 13px;
+}
+*+html #footer-global li {
+    margin: 0 13px 0 0;
+}
+*+[dir='rtl'] #footer-global li {
+    margin: 0 0 0 13px;
+}
+#footer-global li a {
+    font-weight: normal;
+}
+.locales {
+  margin: 10px 0 0 0px;
+}
+[dir='rtl'] .locales {
+    background-position: right center;
+    float: left;
+    padding: 0 24px 0 0;
+}
+.locales form {
+    margin: 0;	
+}
+.locales select, .sites select {
+  line-height: 3.08;
+  margin: 0px 0;
+  border: solid 1px #EBEBEB;
+  -webkit-appearance: none;
+  background: white url('../images/arrows-up-down.png') right center no-repeat;
+  height: 30px;
+  color: #222;
+  line-height: normal;
+  padding: 5px;
+  width: 230px;
+}
+}
+
+/* =============================================================================
+   Print Only
+   ========================================================================== */
+@media print {
+a {
+    color: inherit;
+}
+.nav-x, .nav-y {
+    display: none;
+}
+.str { color: #060; }
+.kwd { color: #006; font-weight: bold; }
+.com { color: #600; font-style: italic; }
+.typ { color: #404; font-weight: bold; }
+.lit { color: #044; }
+.pun { color: #440; }
+.pln { color: #000; }
+.tag { color: #006; font-weight: bold; }
+.atn { color: #404; }
+.atv { color: #060; }
+}
+
+/* =============================================================================
+   Columns
+   ========================================================================== */
+
+@media screen, projection, print {
+.full {
+	padding: 2.5em 0;
+	border-top: solid 1px #ddd;
+	border-bottom: solid 1px #ddd;
+	background: #f7f7f7;	
+}
+.wrap {
+	margin: 0 auto;
+	width: 940px;
+	clear: both;
+}
+.cols {
+    height: 1%;
+    margin: 0 -1.533742331288343558282%;
+    width: 103.06748466257669%}
+*+html .cols {
+    margin-bottom: 20px;
+}
+.cols:after {
+    clear: both;
+    content: ' ';
+    display: block;
+    height: 0;
+    visibility: hidden;
+}
+.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12,
+.col-13, .col-14, .col-15, .col-16 {
+    display: inline;
+	float: left;
+	margin-left: 10px;
+	margin-right: 10px;
+}
+/*
+* html .col-1, * html .col-2, * html .col-3, * html .col-4, * html .col-5, * html .col-6, * html
+.col-7, * html .col-8, * html .col-9, * html .col-10, * html .col-11, * html .col-12  {
+    margin: 0;
+    padding: 0 1.4% 20px;
+}
+[dir='rtl'] .col-1, [dir='rtl'] .col-2, [dir='rtl'] .col-3, [dir='rtl'] .col-4, [dir='rtl'] .col-5,
+[dir='rtl'] .col-6, [dir='rtl'] .col-7, [dir='rtl'] .col-8, [dir='rtl'] .col-9, [dir='rtl'] .col-10,
+[dir='rtl'] .col-11, [dir='rtl'] .col-12 {
+    float: right;
+}
+*/
+.col-1 { width: 40px }
+.col-2 { width: 100px }
+.col-3 { width: 160px }
+.col-4 { width: 220px }
+.col-5 { width: 280px }
+.col-6 { width: 340px }
+.col-7 { width: 400px }
+.col-8 { width: 460px }
+.col-9 { width: 520px }
+.col-10 { width: 580px }
+.col-11 { width: 640px }
+.col-12 { width: 700px }
+.col-13 { width: 760px }
+.col-14 { width: 820px }
+.col-15 { width: 880px }
+.col-16 { width: 940px }
+}
+
+.col-right {
+  margin-right:0px;
+}
+
+@media screen and (max-width:772px) {
+.col-5, .col-6, .col-7 {
+    clear: both;
+    width: 97.0238096%}
+}
+
+/* =============================================================================
+   Layout
+   ========================================================================== */
+@media screen, projection, print {
+
+/* --------------------------------------------------------------------------
+Header, Login, Nav-X, Search
+*/
+#header {
+	padding: 2.2em 0 0.2em 0;
+}
+#header:before, #header:after {
+	content: "";
+	display: table;
+	clear: both
+}
+.logo, .nav-x {
+    float: left;
+}
+.nav-x {
+    margin-top: -2px;
+	list-style-type: none;
+}
+.nav-x a {
+    color: #333;
+    font-size: 16px;
+}
+.design a.selected {
+    color: #33b5e5;
+}
+.develop a.selected {
+    color: #F80;
+}
+.distribute a.selected {
+    color: #9C0;
+}
+
+
+
+.nav-x li {
+    display: inline;
+    margin-right: 45px;
+}
+.search {
+	float: right;
+	position: relative;
+	width: 220px
+}
+.search .bottom, .search .left, .search .right {
+	position: absolute;
+	background-color: #a3a3a3;
+}
+.search .bottom {
+	width: 220px;
+	height: 1px;
+	top: 24px;
+	left: 0
+}
+.search .left, .search .right {	
+	height: 5px;
+	width: 1px
+}
+.search .left {	top: 19px; left: 0 }
+.search .right { top: 19px; right: 0 }
+.search form {
+	float: left;
+	margin-top: 2px;
+	width: inherit;
+}
+.search .close,
+#player-frame .close {
+  position: absolute;
+  right: 8px;
+  bottom: 4px;
+  width: 16px;
+  height: 16px;
+  margin: 0;
+  text-indent: -1000em;
+  background: url(../images/close.png) no-repeat 0 0;
+  z-index:9999;
+}
+.search .close:hover, .search .close:focus,
+#player-frame .close:hover, #player-frame .close:focus {
+  background-position: -16px 0;
+  cursor:pointer;
+}
+#player-frame .close {
+  top: 6px;
+}
+.search form input {
+	color: #999;
+	font-size: 1em;
+	width: inherit;
+	border: none;
+	margin: 0;
+	padding:0 0 0 6px;
+	z-index: 1500;
+	background-color: transparent
+}
+.search:hover .bottom, .search:hover .left, .search:hover .right {
+	background-color: #33b5e5;
+}
+.search:hover .icon {
+	background-position: -8px 0
+}
+.search form input:focus {
+	color: #222;
+	font-weight: bold;
+	outline:0;
+}
+/* Search Dropdown */
+.search-dropdown {
+	padding: 15px;
+	width: 192px;
+	border: solid 1px #c5c5c5;
+	background: #fff;
+	position: absolute;
+	top: 35px;
+	left: 0;
+	-moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+	-webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+	box-shadow: 0  0 10px rgba(0,0,0,0.2)
+}
+.search-dropdown ul, .search-dropdown ul li {
+	list-style-type: none;
+	margin: 0;
+	padding: 0
+}
+.search-dropdown ul li {
+	clear: both	
+}
+.search-dropdown img {
+	float: left;
+	margin: 0 10px 10px 0
+}
+.search-dropdown h6 {
+	color: #222;
+	margin: 0;
+	line-height: normal
+}
+.search-dropdown .desc {
+	color: #999;
+	font-size: 11.5px;
+	line-height: normal;
+	margin: 0;
+}
+.search-dropdown li a:hover h6, .search-dropdown li a:hover .desc {
+	color: #33b5e5
+}
+/* --------------------------------------------------------------------------
+Buttons
+*/
+.button, a.button, .button-secondary, a.button-secondary {
+	border-image: initial;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    cursor: pointer;
+}
+.button, a.button {
+    background-color: #09c;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2faddb), to(#09c));
+    background-image: -webkit-linear-gradient(top, #2faddb, #09c);
+    background-image: -moz-linear-gradient(top, #2faddb, #09c);
+    background-image: -ms-linear-gradient(top, #2faddb, #09c);
+    background-image: -o-linear-gradient(top, #2faddb, #09c);
+    background-image: linear-gradient(top, #2faddb, #09c);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#0099cc',GradientType=0);
+    border: 1px solid #3990ab;
+    color: #fff;
+}
+.button-secondary, a.button-secondary {
+    background-color: #f3f3f3;
+    border: 1px solid #dcdcdc;
+    color: #444;
+}
+a.button, a.button:visited, a.button-secondary, a.button-secondary:visited {
+    height: 28px;
+    line-height: 28px;
+    margin-right: 16px;
+	font-weight: 400;
+    min-width: 54px;
+    outline: 0;
+    padding: 8px 15px;
+    text-align: center;
+}
+.button, .button-secondary {
+    height: 34px;
+    line-height: 34px;
+    margin-right: 16px;
+	font-weight: 400;
+    min-width: 54px;
+    outline: 0;
+    padding: 0 15px;
+    text-align: center;
+}
+.button:hover, a.button:hover {
+    border-color: #09c;
+    background-color: #4cadcb;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#5dbcd9), to(#4cadcb));
+    background-image: -webkit-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -moz-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -ms-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -o-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: linear-gradient(top, #5dbcd9, #4cadcb);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5dbcd9',
+EndColorStr='#4cadcb',GradientType=0);
+    color: #fff !important;
+}
+.button:active, a.button:active {
+    background-color: #1e799a;
+    background-image: none;
+    border-color: #30b7e6;
+}
+.button-secondary:hover, a.button-secondary:hover {
+    border-color: #dbdbdb;
+    background-color: #f3f3f3;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
+    background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -moz-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -ms-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -o-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: linear-gradient(top, #f9f9f9, #ececec);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+    color: #33B5E5 !important;
+}
+.button-secondary:active, a.button-secondary:active {
+    border-color: #dadada;
+	background: #ebebeb; /* Old browsers */
+	/* IE9 SVG, needs conditional override of 'filter' to 'none' */
+	background:
+url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/
+Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0Jv
+eD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+
+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIg
+eDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ViZWJl
+YiIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjEwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2ZhZmFmYSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjkwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNmY2ZjYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFy
+R3JhZGllbnQ+
+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIg
+Lz4KPC9zdmc+);
+	background: -moz-linear-gradient(top,  #ebebeb 0%, #f9f9f9 5%, #fafafa 50%, #f9f9f9 90%,
+#ffffff 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ebebeb),
+color-stop(5%,#f9f9f9), color-stop(50%,#fafafa), color-stop(90%,#f9f9f9), color-stop(100%,#ffffff));
+/* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9
+90%,#ffffff 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* IE10+ */
+	background: linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ebebeb',
+endColorstr='#ffffff',GradientType=0 ); /* IE6-8 */
+	-webkit-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	-moz-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05); 
+	color: #258AAF !important;
+}
+.button.big {
+  font-size:20px;
+  display:inline-block;
+}
+
+.button.disabled,
+.button.disabled:hover,
+.button.disabled:active {
+  background:#ebebeb;
+  color:#999;
+  border-color:#999;
+  cursor:default;
+}
+
+.training-nav-top a.button-secondary,
+.training-nav-bottom a.button-secondary {
+  display:block;
+  float:left;
+  margin:0;
+  width:130px;
+  text-transform:uppercase;
+  font-weight:bold;
+  
+    background-color: #f3f3f3;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
+    background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -moz-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -ms-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -o-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: linear-gradient(top, #f9f9f9, #ececec);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+    color: #33B5E5;
+}
+
+.training-nav-top a.button-secondary:hover,
+.training-nav-bottom a.button-secondary:hover {
+    background-color: #09c;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2faddb), to(#09c));
+    background-image: -webkit-linear-gradient(top, #2faddb, #09c);
+    background-image: -moz-linear-gradient(top, #2faddb, #09c);
+    background-image: -ms-linear-gradient(top, #2faddb, #09c);
+    background-image: -o-linear-gradient(top, #2faddb, #09c);
+    background-image: linear-gradient(top, #2faddb, #09c);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#09c');
+    border: 1px solid #3990ab;
+    color: #fff !important;
+}
+
+.training-nav-top a.button-secondary.last,
+.training-nav-bottom a.button-secondary.last {
+  border-left:0;
+}
+
+.training-nav-top a.button-secondary.double-size,
+.training-nav-bottom a.button-secondary.double-size {
+  width:291px;
+}
+
+.training-nav-top,
+.training-nav-bottom {
+  float:right;
+  margin:0 0 0 20px;
+}
+
+.training-nav-bottom {
+  padding:0 0 20px;
+}
+
+#tb-wrapper,
+#qv-wrapper {
+  float:right;
+  clear:right;
+  margin:-27px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
+  padding:0 0 20px;
+}
+
+#tb,
+#qv {
+  font-size:13px;
+  line-height:18px;
+  width:238px;
+  border:1px solid #ccc;
+  float:right;
+}
+
+#tb {
+  width:278px;
+}
+
+#tb h2,
+#qv h2 {
+  margin:10px 15px;
+  padding:0;
+  text-transform:uppercase;
+  border-bottom:1px solid gainsboro;
+}
+
+#tb *,
+#qv * {
+  font-size:inherit;
+}
+
+#tb .download-box {
+  padding:0 0 0 15px;
+}
+
+#tb .download-box .filename {
+  font-size:11px;
+  margin:4px 4px 10px;
+  color:#666;
+}
+
+
+/* Dev guide quicknav */
+
+.sidebox-wrapper {
+  float:right;
+  clear:right;
+  margin:0 0 0 20px;
+  padding:0 0 20px;
+}
+
+.sidebox {
+  width:226px;
+  font-size:13px;
+  line-height:18px;
+  border-left:4px solid #99CC00;
+  float:right;
+  padding:0 0 0 10px;
+}
+
+.sidebox h2,
+.sidebox h3,
+.sidebox h4,
+.sidebox h5 {
+  font-weight:bold;
+  margin:0 0 10px;
+}
+
+.sidebox * {
+  font-size:inherit;
+}
+
+#tb ol,
+#tb ul,
+#qv ul {
+  margin:0 15px 10px 35px;
+}
+
+#qv ol {
+  list-style:none;
+  margin:0 15px 15px;
+  font-size:inherit;
+  line-height:inherit;
+}
+
+#tb ol ol,
+#tb ul ul,
+#qv ol ol,
+#qv ul ul,
+.sidebox ol ol,
+.sidebox ul ul {
+  margin-bottom:0;
+}
+
+#qv ol ol {
+  margin:3px 0 3px 15px;
+}
+
+.sidebox p,
+#qv p,
+#tb p {
+  margin: 0 0 10px;
+}
+
+
+/* --------------------------------------------------------------------------
+Form
+*/
+.article form {
+    margin: 0 0 20px;
+}
+.article form .form-required {
+    color: #dd4b39;
+}
+.article form fieldset {
+    margin: 0 0 20px;
+    padding: 0;
+}
+.article form legend {
+    display: block;
+    line-height: 1.5;
+    margin: 0;
+    padding: 0;
+}
+/*
+.article form ol, .article form ul {
+    margin: 0 0 0 1em;
+    padding: 0 0 0 1em;
+}
+[dir='rtl'] .article form ol, [dir='rtl'] .article form ul {
+    margin: 0 1em 0 0;
+    padding: 0 1em 0 0;
+}
+.article form ol ul, .article form ul ul, [dir='rtl'] .article form ol ul, [dir='rtl'] .article form
+ul ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+.article form li {
+    margin: 0 0 20px;
+}
+.article form li li {
+    margin: 0 0 5px;
+}
+*/
+.article form label {
+    display: block;
+    margin: 0 0 5px;
+    padding: 0;
+}
+.article form input[type='text'], .article form select, .article form textarea, .article form
+.checkbox-group, .article form .radio-group {
+    margin-bottom: 15px;
+}
+.checkbox-group input {
+	width: 13px;
+	height: 13px;
+	background: #fff;
+	border: solid 1px #c6c6c6;
+	float: left;
+}
+.article form .checkbox-group, .article form .radio-group {
+	display: block
+}
+.article form select {
+    border: solid 1px #ebebeb;
+    border-top-color: #ddd;
+    -webkit-appearance: none;
+    background: #f3f3f3 url(../images/arrows-up-down.png) right center no-repeat;
+    height: 30px;
+    color: #222;
+    line-height: normal;
+    padding: 5px;
+    width: 130px;
+}
+    
+.article form .browse .browse-msg {
+	font-size: 11.5px;	
+}
+.article form .browse .button-secondary {
+	height: auto;
+	line-height: 25px;
+	font-size: 11px;
+	padding: 0 8px;
+	margin: 0 10px 15px 0;
+}
+.article form input[type='text'], .article form textarea {
+    border: 1px solid #ebebeb;
+    border-top-color: #dcdcdc;
+    color: #222;
+    line-height: normal;
+    padding: 6px 10px;
+    width: 300px;	
+}
+.article form textarea {
+    height: 150px;
+}
+.article form input[type='text']:focus, .article form textarea:focus {
+    border-color: #33B5E5;
+    -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    -o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    outline: 0;
+}
+.article form input[disabled], .article form textarea[disabled], .article form label.form-disabled {
+    color: #999;
+}
+.article form input[type='text'][disabled], .article form textarea[disabled] {
+    background-color: #ebebeb;
+}
+form .form-error input[type='text'], form .form-error textarea {
+    border-color: #dd4b39;
+	margin-right: 20px;
+}
+.aside {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+    margin: 10px 0;
+    padding: 20px;
+	color: #666;
+    position: relative;
+	background: #f9f9f9;
+}
+/*
+.aside, .notification, .promo {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+    margin: 10px 0;
+    padding: 10px;
+    position: relative;
+}
+.aside>:first-child, .notification>:first-child, .promo>:first-child {
+    margin-top: 0;
+}
+.aside>:last-child, .notification>:last-child, .promo>:last-child {
+    margin-bottom: 0;
+}
+.aside {
+    background: #f9f9f9;
+}
+.notification {
+    background: #fffbe4;
+    border-color: #f8f6e6;
+}
+.promo {
+    background: #f6f9ff;
+    border-color: #eff2f9;
+}
+*/
+/* --------------------------------------------------------------------------
+Code Style
+*/
+pre {
+	margin: 1em 0;
+	padding: 1em;
+	overflow: auto;
+	border: solid 1px #ddd;
+	background: #f7f7f7;	
+}
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #828; }
+.atv { color: #080; }
+.dec { color: #606; }
+
+/* --------------------------------------------------------------------------
+Three-Pane
+*/
+/* Package Nav & Classes Nav */
+.three-pane {
+	position: relative;
+	border-top: solid 1px #ebebeb;
+}
+#packages-nav .js-pane,
+#classes-nav .js-pane {
+  overflow:visible;
+}
+#packages-nav {
+        height:270px;
+	max-height: inherit;
+	overflow: hidden;
+	position: relative;	
+}
+#classes-nav {
+	overflow: hidden;
+	position: relative;	
+}
+#packages-nav ul, #classes-nav ul {
+	list-style-type: none;
+	margin: 10px 0 20px 0;
+	padding: 0;	
+}
+#classes-nav li {
+	font-weight: bold;
+	margin: 5px 0;
+}
+#packages-nav li,
+#classes-nav li li {
+	margin: 0;
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li a, #classes-nav li a:active, #classes-nav li a:visited {
+	padding: 0 0 0 4px;
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li li a, #classes-nav li li a:active, #classes-nav li li a:visited,
+#nav-tree li a, #nav-tree li a:active, #nav-tree li a:visited {
+	color: #222;
+	font-weight: normal;	
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li li a, #classes-nav li li a:active, #classes-nav li li a:visited {
+	display: block;
+}
+#packages-nav li.selected a, #packages-nav li.selected a:active, #packages-nav li.selected
+a:visited,
+#classes-nav li li.selected a, #classes-nav li li.selected a:active, #classes-nav li li.selected
+a:visited,
+#nav-tree li div.selected {
+    font-weight: 500;
+    color: #0099cc;
+    background-color:#fff; }
+  #packages-nav li.selected ul li a,
+  #classes-nav li.selected ul li a {
+  /* don't highlight child items */
+    color: #555555; }
+#nav-tree li div.selected a {
+    font-weight: 500;
+    color: #0099cc;
+}
+#nav-swap {
+  height:30px;
+  border-top:1px solid #ccc;
+}
+#nav-swap a {
+  display:inline-block;
+  height:100%;
+  color: #222;
+  font-size: 12px;
+  padding: 5px 0 5px 5px;
+}
+
+#nav-swap .fullscreen {
+  float: right;
+  width: 24px;
+  height: 24px;
+  text-indent: -1000em;
+  padding:0;
+  margin:3px 5px 0;
+  background: url(../images/fullscreen.png) no-repeat -24px 0;
+}
+#nav-swap .fullscreen.disabled {
+  background-position: 0 0;
+}
+#nav-swap .fullscreen:hover, 
+#nav-swap .fullscreen:focus {
+  cursor:pointer;
+}
+
+
+/* nav tree */
+#side-nav, #devdoc-nav, #swapper,
+#nav-tree, #tree-list {
+  overflow:hidden;
+  margin-left:0;
+}
+
+#nav-tree ul {
+  list-style:none;
+  padding:0;
+  margin:10px 0;
+}
+
+#nav-tree ul li div {
+  padding:0 0 0 4px;
+}
+
+#side-nav #nav-tree ul li a,
+#side-nav #nav-tree ul li span.no-children {
+  padding: 0;
+  margin: 0;
+}
+
+#nav-tree .plus {
+  margin: 0 3px 0 0;
+}
+
+#nav-tree ul ul {
+  list-style: none;
+  margin: 0;
+  padding: 0 0 0 0;
+}
+
+#nav-tree ul li {
+  margin: 0;
+  padding: 0 0 0 0;
+  white-space: nowrap;
+}
+
+#nav-tree .children_ul {
+  padding:0;
+  margin:0;
+}
+#nav-tree .children_ul li div {
+  padding:0 0 0 10px;
+}
+#nav-tree .children_ul .children_ul li div {
+  padding:0 0 0 20px;
+}
+
+#nav-tree a.nolink {
+  color: #222;
+  text-decoration: none;
+}
+
+#nav-tree span.label {
+  width: 100%;
+}
+
+#nav-tree {
+  overflow-x: auto;
+  overflow-y: scroll;
+  outline:0;
+}
+
+
+/* Content */
+#doc-col {
+  margin-right:0;
+}
+#doc-content-container {
+	margin-left: 291px	
+}
+#doc-header, #doc-content {
+	padding: 1em 2em;
+}
+#doc-header {
+	background: #f7f7f7;	
+}
+#doc-header h1 {
+	line-height: 0;
+	margin-bottom: 15px;
+}
+#api-info-block {
+	float: right;
+	font-weight: bold;
+}
+#api-info-block a, #api-info-block a:active, #api-info-block a:visited {
+	color: #222;
+}
+#api-info-block a:hover, #api-info-block a:focus {
+	color: #33B5E5;
+}
+#api-nav-header {
+  height:19px; /* plus 16px padding = 35; same as #nav li */
+  font-size:14px;
+  padding: 8px 0;
+  margin: 0;
+  border-bottom: 1px solid #CCC;
+  background:#e9e9e9;
+  background: rgba(0, 0, 0, 0.05); /* matches #nav li.expanded */
+
+}
+#api-nav-title {
+  padding:0 5px;
+  white-space:nowrap;
+}
+
+#api-level-toggle {
+  float:right;
+  padding:0 5px;
+}
+
+#api-level-toggle label {
+  margin:0;
+  vertical-align:top;
+  line-height: 19px;
+  font-size:13px;
+  height: 19px;
+}
+
+#api-level-toggle .select-wrapper {
+  width: 35px;
+  display: inline-block;
+  overflow: hidden;
+}
+#api-level-toggle select {
+  border: 0;
+  appearance:none;
+  -moz-appearance:none;
+  -webkit-appearance: none;
+  background: transparent url(../images/arrows-up-down.png) 23px 5px no-repeat;
+  color: #222;
+  height: 19px;
+  line-height: 19px;
+  padding: 0;
+  margin:1px 0 0 0;
+  width:150%;
+  font-size:13px;
+  vertical-align:top;
+  outline:0;
+}
+
+
+/* Toggle for revision notes and stuff */
+div.toggle-content.closed .toggle-content-toggleme {
+  display:none;
+}
+
+#jd-content img.toggle-content-img {
+  margin:0 5px 5px 0;
+}
+div.toggle-content > p {
+  padding:0 0 5px;
+}
+
+
+/* API LEVEL FILTERED MEMBERS */
+
+.absent,
+.absent a:link,
+.absent a:visited,
+.absent a:hover,
+.absent * {
+  color:#bbb !important;
+  cursor:default !important;
+  text-decoration:none !important;
+}
+#devdoc-nav li.absent.selected,
+#devdoc-nav li.absent.selected *,
+#devdoc-nav div.label.absent.selected,
+#devdoc-nav div.label.absent.selected * {
+  background-color:#eaeaea !important;
+}
+.absent h4.jd-details-title,
+.absent h4.jd-details-title * {
+  background-color:#f6f6f6 !important;
+}
+.absent img {
+  opacity: .3;
+  filter: alpha(opacity=30);
+  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
+}
+
+
+
+
+
+
+
+
+
+/* JQUERY RESIZABLE STYLES */
+.ui-resizable { position: relative; }
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; z-index:1; }
+.ui-resizable .ui-resizable-handle { display: block; border-bottom: 1px solid #e4e4e4; }
+/*body .ui-resizable-disabled .ui-resizable-handle { display: none; }
+body .ui-resizable-autohide .ui-resizable-handle { display: none; }*/
+.ui-resizable-s { cursor: s-resize; height: 10px; width: 100% !important; bottom: -11px; left: 0;
+border-bottom: solid 1px #ededed;
+  background: #f7f7f7 url("../images/resizable-s2.png") no-repeat scroll center center; }
+/*
+.ui-resizable-e { 
+cursor: e-resize; width: 10px; right: 0; top: 0; height: 100%; border-right: solid
+1px #ededed;background: #f7f7f7 url("../images/resizable-e2.png") no-repeat scroll center center; }
+*/
+
+/* --------------------------------------------------------------------------
+Lightbox
+*/
+.lightbox {	
+	width: 769px;
+	padding: 1.5em;
+	margin: 0 auto;
+	border: solid 1px #dcdcdc;
+	background: #fff;
+	-moz-box-shadow: 1px 1px 5px rgba(0,0,0,0.1);
+	-webkit-box-shadow: 1px 1px 5px rgba(0,0,0,0.1);
+	box-shadow: 1px 1px 5px rgba(0,0,0,0.1)
+}
+.lightbox .header {
+	float: left;
+	width: 720px;
+	margin: -10px 20px 10px 0;	
+}
+.lightbox .close {
+	float: right;
+	width: 10px;
+	height: 10px;
+	margin: -10px -10px 10px 0;
+	text-indent: -1000em;
+	background: url(../images/close.png) no-repeat 0 0;
+}
+.lightbox .close:hover, .lightbox .close:focus {
+	background-position: -10px 0;
+}
+
+/* --------------------------------------------------------------------------
+Misc
+*/
+
+
+.clearfix:before, .clearfix:after {
+	content: "";
+	display: table
+}
+.clearfix:after {
+	clear: both
+}
+.clearfix {
+	*zoom: 1
+}
+table.blank th, table.blank td {
+    border: 0;
+	background: none
+}
+.caption {
+	margin: 0.5em 0 2em 0;
+	color: #000;
+	font-size: 11.5px;	
+}
+
+.nolist {
+  list-style:none;
+  padding:0;
+  margin:0 0 1em 1em;
+}
+
+.nolist li {
+  padding:0 0 2px;
+  margin:0;
+}
+
+pre.classic {
+  background-color:transparent;
+  border:none;
+  padding:0;
+}
+
+p.img-caption {
+  margin: -10px 0 20px;
+  font-size:13px;
+  color:#666;
+}
+
+div.figure {
+  float:right;
+  clear:right;
+  margin:10px 0 0 0;
+  padding:0 0 0 20px;
+  /* width must be defined w/ an inline style matching the image width */
+}
+
+p.table-caption {
+  margin: 0 0 4px 0; /* matches default table left-margin */
+  font-size:13px;
+  color:#666;
+}
+
+p.note, div.note, 
+p.caution, div.caution, 
+p.warning, div.warning {
+  padding: 0 0 0 10px;
+  border-left: 4px solid;
+}
+
+p.note {
+  border-color: #258AAF;
+}
+
+p.caution {
+  border-color: #FF8800;
+}
+
+p.warning {
+  border-color: #ff4443;
+}
+
+div.note.design {
+  border-left: 4px solid #33B5E5;
+}
+
+div.note.develop {
+  border-left: 4px solid #F80;
+}
+
+div.note.distribute {
+  border-left: 4px solid #9C0;
+}
+
+.note p, .caution p, .warning p {
+  margin:0 0 5px;
+}
+
+.note p:last-child, .caution p:last-child, .warning p:last-child {
+  margin-bottom:0;
+}
+
+blockquote {
+  display:block;
+  float:right;
+  width:280px;
+  font-size:20px;
+  font-style:italic;
+  line-height:24px;
+  color:#33B5E5;
+  margin:0 0 20px 30px;
+}
+
+div.design-announce p {
+  margin:0 0 10px;
+}
+
+#devdoc-nav a.totop {
+  display:block;
+  top:0;
+  width:inherit;
+  background: transparent url(../images/styles/gototop.png) no-repeat scroll 50% 50%;
+  text-indent:-9999em;
+}
+#devdoc-nav a.totop {
+  position:fixed;
+  display:none;
+}
+#devdoc-nav a.totop:hover {
+  background-color:#33B5E5;
+}
+
+.content-footer a.totop {
+  text-transform:uppercase;
+  line-height:30px;
+}
+
+/* -----------------------------------------------
+Dialog box for popup messages 
+*/
+
+div.dialog {
+  height:0;
+  margin:0 auto;
+}
+
+div.dialog>div {
+  z-index:99;
+  position:fixed;
+  margin:70px 0;
+  width: 391px;
+  height: 200px;
+  background: #F7F7F7;
+-moz-box-shadow: 0 0 15px rgba(0,0,0,0.5);
+-webkit-box-shadow: 0 0 15px rgba(0,0,0,0.5);
+box-shadow: 0 0 15px rgba(0,0,0,0.5);
+}
+/* IE6 can't position fixed */
+* html div.dialog div { position:absolute; }
+
+
+div#deprecatedSticker {
+  display:none;
+  z-index:99;
+  position:fixed;
+  right:15px;
+  top:114px;
+  margin:0;
+  padding:1em;
+  background:#FFF;
+  border:1px solid #dddd00;
+  box-shadow:-5px 5px 10px #ccc;
+  -moz-box-shadow:-5px 5px 10px #ccc;
+  -webkit-box-shadow:-5px 5px 10px #ccc;
+}
+
+div#naMessage {
+  display:none;
+  width:555px;
+  height:0;
+  margin:0 auto;
+}
+
+div#naMessage div {
+  z-index:99;
+  width:450px;
+  position:fixed;
+  margin:50px 0;
+  padding:4em 4em 3em;
+  background:#FFF;
+  border:1px solid #999;
+  box-shadow:-10px 10px 40px #888;
+  -moz-box-shadow:-10px 10px 40px #888;
+  -webkit-box-shadow:-10px 10px 40px #888;
+}
+/* IE6 can't position fixed */
+* html div#naMessage div { position:absolute; }
+
+div#naMessage strong {
+  font-size:1.1em;
+}
+
+
+/* --------------------------------------------------------------------------
+Slideshow Controls & Next/Prev 
+*/
+.slideshow-next, .slideshow-prev {	
+	width: 20px;
+	height: 36px;
+	text-indent: -1000em;
+}
+.slideshow-container {
+	margin: 2em 0;
+}
+.slideshow-container:before, .slideshow-container:after {
+	content: "";
+	display: table;
+	clear: both;
+}
+a.slideshow-next, a.slideshow-next:visited {
+
+	float: right;
+
+	background: url(../images/arrow-right.png) no-repeat 0 0
+
+}
+
+a.slideshow-prev, a.slideshow-prev:visited {
+
+	float: left;	
+
+	background: url(../images/arrow-left.png) no-repeat 0 0
+
+}
+
+.slideshow-next:hover, .slideshow-prev:hover, .slideshow-next:focus, .slideshow-prev:focus {
+
+	background-position: 0 -36px	
+
+}
+
+.slideshow-next:active, .slideshow-prev:active {
+
+	background-position: 0 -72px	
+
+}
+.slideshow-nav {
+	width: 74px;
+	margin: 0 auto;		
+}
+.slideshow-nav a, .slideshow-nav a:visited {
+	display: inline-block;
+	width: 12px;
+	height: 12px;
+	margin: 0 2px 20px 2px;
+	background: #ccc;
+	-webkit-border-radius: 50%;
+	-moz-border-radius: 50%;
+	border-radius: 50%;
+}
+.slideshow-nav a:hover, .slideshow-nav a:focus {
+
+	background: #33B5E5
+}
+
+.slideshow-nav a:active {
+
+	background: #1e799a;
+	background: #ebebeb;	
+	-webkit-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	-moz-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+}
+.slideshow-nav a.active, .slideshow-nav a.active:active, .slideshow-nav a.active:visited {
+	background: #33B5E5
+}
+/* --------------------------------------------------------------------------
+Tabs
+*/
+ul.tabs {
+	padding: 0;
+	margin: 2em 0 0 0;	
+}
+ul.tabs:before, ul.tabs:after {
+	content: "";
+	display: table;
+	clear: both;
+}
+ul.tabs li {
+	list-style-type: none;
+	float: left;	
+}
+ul.tabs li a, ul.tabs li a:active, ul.tabs li a:visited {
+	display: block;
+	height: 36px;
+	line-height: 36px;
+	padding: 0 15px;
+	margin-right: 2px;
+	color: #222;
+	-moz-border-radius-topleft: 2px;
+	-moz-border-radius-topright: 2px;
+	-moz-border-radius-bottomright: px;
+	-moz-border-radius-bottomleft: px;
+	-webkit-border-radius: 2px 2px px px;
+	border-radius: 2px 2px px px; 
+	border-top: solid 1px #ebebeb;
+	border-left: solid 1px #ebebeb;
+	border-right: solid 1px #ebebeb;
+	background-color: #fff;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#fafafa));
+    background-image: -webkit-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -moz-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -ms-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -o-linear-gradient(top, #ffffff, #fafafa);
+    background-image: linear-gradient(top, #ffffff, #fafafa);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff',
+EndColorStr='#fafafa');
+}
+ul.tabs li a:hover {
+	color: #33B5E5;	
+}
+ul.tabs li a.selected {
+	height: 37px;
+	color: #33B5E5;
+	background-color: #f7f7f7;
+	background-image: none;
+	border-color: #ddd;
+}
+.tab-content {
+	padding: 1.2em;
+	margin: -1px 0 2em 0;
+	-webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+	border: solid 1px #ddd;
+	background: #f7f7f7;
+}
+/* --------------------------------------------------------------------------
+Feature Boxes
+*/
+.feature-box {
+  width: 291px;
+  height: 200px;
+  position: relative;
+  background: #F7F7F7;
+}
+.box-border .top, .box-border .bottom, .box-border .left, .box-border .right {
+	z-index: 100;
+	position: absolute;
+	background-color: #aaa;
+}
+.box-border .top, .box-border .bottom {
+	width: 291px;
+	height: 1px;
+}
+.dialog .box-border .top,
+.dialog .box-border .bottom { width:391px; }
+
+.box-border .left, .box-border .right {	
+	width: 1px;
+	height: 8px;		
+}
+.box-border .top { top: 0; left: 0 }
+.box-border .top .left { top: 1px; left: 0 }
+.box-border .top .right { top: 1px; right: 0 }
+.box-border .bottom .left { top: -8px; left: 0 }
+.box-border .bottom { top: 200px; left: 0 }
+.box-border .bottom .right { top: -8px; right: 0 }
+
+.feature-box h4,
+.dialog h4 {
+    margin: 15px 18px 10px;
+    padding:0;
+}
+
+.feature-box p,
+.dialog p {
+    margin: 10px 18px;
+    padding:0;
+}
+.feature-box .link,
+.dialog .link {
+    border-top: 1px solid #dedede;
+    bottom: 0;
+    position: absolute;
+    width: inherit;
+}
+.feature-box a, .feature-box h4,
+.dialog a, .dialog h4 {
+    -webkit-transition: color .4s ease;
+    -moz-transition: color .4s ease;
+    -o-transition: color .4s ease;
+    transition: color .4s ease;
+}
+.feature-box:hover {
+	cursor: pointer;	
+}
+.feature-box:hover .box-border .top, .feature-box:hover .box-border .bottom, .feature-box:hover
+.left, .feature-box:hover .right {	
+	background-color: #33B5E5;
+}
+.feature-box:hover h4, .feature-box:hover a {
+	color: #33B5E5;
+}
+/* --------------------------------------------------------------------------
+Page-Specific Styles
+*/
+.colors { 
+	position: relative;
+	float: left;
+	width: 92px;
+	margin: 40px 0 20px;
+}
+.colors div {
+	color: #fff;
+	font-size: 11.5px;
+	width: 82px;
+	height: 82px;
+	margin-top:-30px;
+	line-height: 82px;
+	text-align: center;
+	border: solid 5px #fff;
+	-webkit-border-radius: 50%;
+	-moz-border-radius: 50%;
+	border-radius: 50%;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ########### REFERENCE DOCS ################## */
+
+#packages-nav h2,
+#classes-nav h2 {
+  font-size:18px;
+  margin:0;
+  padding:0 0 0 4px;
+}
+
+#jd-header {
+  padding: 0 0 5px;
+  margin: 20px 0 10px;
+  font-size:13px;
+  border-bottom:solid 1px #ccc;
+}
+
+#jd-header h1 {
+  margin:0;
+  padding:0;
+}
+
+/* page-top-right container for reference pages (holds
+links to summary tables) */
+#api-info-block {
+  font-size:13px;
+  margin:20px 0 0;
+  padding:0 10px 6px;
+  font-weight:normal;
+  float:right;
+  text-align:right;
+  color:#999;
+  max-width:70%;
+}
+
+#api-info-block div.api-level {
+  font-weight:bold;
+  font-size:inherit;
+  float:none;
+  color:#222;
+  padding:0;
+  margin:0;
+}
+
+/* inheritance table */
+.jd-inheritance-table {
+  border-spacing:0;
+  margin:0;
+  padding:0;
+  font-size:13px;
+  background-color:transparent;
+}
+.jd-inheritance-table tr td {
+  border: none;
+  margin: 0;
+  padding: 0;
+  background-color:transparent;
+}
+.jd-inheritance-table .jd-inheritance-space {
+  font-weight:bold;
+  width:1em;
+}
+.jd-inheritance-table .jd-inheritance-interface-cell {
+  padding-left: 17px;
+}
+
+
+
+.jd-sumtable a {
+  text-decoration:none;
+}
+
+.jd-sumtable a:hover {
+  text-decoration:underline;
+}
+
+/* the link inside a sumtable for "Show All/Hide All" */
+.toggle-all {
+  display:block;
+  float:right;
+  font-weight:normal;
+  font-size:0.9em;
+}
+
+/* adjustments for in/direct subclasses tables */
+.jd-sumtable.jd-sumtable-subclasses {
+  margin: 1em 0 0 0;
+  max-width:968px;
+  background-color:transparent;
+  font-size:13px;
+}
+
+/* extra space between end of method name and open-paren */
+.sympad {
+  margin-right: 2px;
+}
+
+/* right alignment for the return type in sumtable */
+.jd-sumtable .jd-typecol {
+  text-align:right;
+}
+
+/* adjustments for the expando table-in-table */
+.jd-sumtable-expando {
+  margin:.5em 0;
+  padding:0;
+}
+
+/* a div that holds a short description */
+.jd-descrdiv {
+  padding:3px 1em 0 1em;
+  margin:0;
+  border:0;
+}
+
+#jd-content img.jd-expando-trigger-img {
+  padding:0 4px 4px 0;
+  margin:0;
+}
+
+.jd-sumtable-subclasses div#subclasses-direct,
+.jd-sumtable-subclasses div#subclasses-indirect {
+  margin:0 0 0 13px;
+}
+
+
+
+/********* MEMBER REF *************/
+
+
+.jd-details {
+/*  border:1px solid #669999;
+  padding:4px; */
+  margin:0 0 1em;
+}
+
+/* API reference: a container for the
+.tagdata blocks that make up the detailed
+description */
+.jd-details-descr {
+  padding:0;
+  margin:.5em .25em;
+}
+
+/* API reference: a block containing
+a detailed description, a params table,
+seealso list, etc */
+.jd-tagdata {
+  margin:.5em 1em;
+}
+
+.jd-tagdata p {
+  margin:0 0 1em 1em;
+}
+
+/* API reference: adjustments to
+the detailed description block */
+.jd-tagdescr {
+  margin:.25em 0 .75em 0;
+}
+
+.jd-tagdescr ol,
+.jd-tagdescr ul {
+  margin:0 2.5em;
+  padding:0;
+}
+
+.jd-tagdescr table,
+.jd-tagdescr img {
+  margin:.25em 1em;
+}
+
+.jd-tagdescr li {
+margin:0 0 .25em 0;
+padding:0;
+}
+
+/* API reference: heading marking
+the details section for constants,
+attrs, methods, etc. */
+h4.jd-details-title {
+  font-size:1.15em;
+  background-color: #E2E2E2;
+  margin:1.5em 0 .6em;
+  padding:3px 95px 3px 3px; /* room for api-level */
+}
+
+h4.jd-tagtitle {
+  margin:0;
+}
+
+h4 .normal {
+  font-weight:normal;
+}
+
+/* API reference: heading for "Parameters", "See Also", etc.,
+in details sections */
+h5.jd-tagtitle {
+  margin:0 0 .25em 0;
+  font-size:1em;
+}
+
+.jd-tagtable {
+  margin:0;
+  background-color:transparent;
+  width:auto;
+}
+
+.jd-tagtable td,
+.jd-tagtable th {
+  border:none;
+  background-color:#fff;
+  vertical-align:top;
+  font-weight:normal;
+  padding:2px 10px;
+}
+
+.jd-tagtable th {
+  font-style:italic;
+}
+
+/* Inline api level indicator for methods */
+div.api-level {
+  font-size:.8em;
+  font-weight:normal;
+  color:#999;
+  float:right;
+  padding:0 8px 0;
+  margin-top:-30px;
+}
+
+table.jd-tagtable td,
+table.jd-tagtable th {
+  background-color:transparent;
+}
+
+table.jd-tagtable th {
+  color:inherit;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* SEARCH FILTER */
+
+#search_autocomplete {
+  font-weight:normal;
+}
+
+#search_filtered_wrapper {
+  width: 193px;
+  float: right;
+}
+#search_filtered_div {
+  position:absolute;
+  z-index:9999;
+  min-width:171px; /* +padding and border makes this match input width */
+  padding:5px;
+  border: solid 1px #C5C5C5;
+  background: white;
+  top: 35px;
+  -moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+  -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+}
+
+ul#search_filtered {
+  min-width:100%;
+  margin:0;
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+
+#search_filtered li{
+  line-height:1.5em;
+  margin: 0 0 2px;
+  padding: 0;
+}
+
+#search_filtered li a {
+  padding:0 5px;
+  color:#222 !important;
+}
+
+#search_filtered .jd-selected {
+  background-color: #33B5E5;
+  cursor:pointer;
+}
+#search_filtered .jd-selected,
+#search_filtered .jd-selected a {
+  color:#f7f7f7 !important;
+}
+
+.no-display {
+  display: none;
+}
+
+.jd-autocomplete {
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  font-size: 0.81em;
+  border: none;
+  margin: 0;
+  line-height: 1.05em;
+}
+
+.show-item {
+  display: table-row;
+}
+.hide-item {
+  display: hidden;
+}
+
+
+
+
+
+/* SEARCH RESULTS */
+
+/* disable twiddle and size selectors for left column */
+#leftSearchControl div {
+  padding:0;
+}
+
+#leftSearchControl .gsc-twiddle {
+  background-image : none;
+}
+
+#leftSearchControl td, #searchForm td {
+  border: 0px solid #000;
+  padding:0;
+}
+
+#leftSearchControl .gsc-resultsHeader .gsc-title {
+  padding-left : 0px;
+  font-weight : bold;
+  font-size : 13px;
+  color:#006699;
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsHeader div.gsc-results-selector {
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsRoot {
+  padding-top : 6px;
+}
+
+#leftSearchControl div.gs-visibleUrl-long {
+  display : block;
+  color:#006699;
+}
+
+#leftSearchControl .gsc-webResult {
+  padding:0 0 20px 0;
+}
+
+.gsc-webResult div.gs-visibleUrl-short,
+table.gsc-branding,
+.gsc-clear-button {
+  display : none;
+}
+
+.gsc-cursor-box .gsc-cursor div.gsc-cursor-page,
+.gsc-cursor-box .gsc-trailing-more-results a.gsc-trailing-more-results,
+#leftSearchControl a,
+#leftSearchControl a b {
+  color:#006699;
+}
+
+.gsc-resultsHeader {
+  display: none;
+}
+
+/* Disable built in search forms */
+.gsc-control form.gsc-search-box {
+  display : none;
+}
+table.gsc-search-box {
+  margin:6px 0 0 0;
+  border-collapse:collapse;
+}
+
+td.gsc-input {
+  padding:0 2px;
+  width:100%;
+  vertical-align:middle;
+}
+
+input.gsc-input {
+  border:1px solid #BCCDF0;
+  width:99%;
+  padding-left:2px;
+  font-size:.95em;
+}
+
+td.gsc-search-button {
+  text-align: right;
+  padding:0;
+  vertical-align:top;
+}
+
+
+#searchResults {
+  overflow:hidden; /* because the repositioned page links makes the section think it needs to scroll
+(it doesn't) */
+  height:auto;
+}
+
+#searchResults .gsc-control {
+  position:relative;
+  width:auto;
+  padding:0 0 10px;
+}
+
+#searchResults .gsc-tabsArea {
+  position:relative;
+  white-space:nowrap;
+  float:left;
+  width:200px;
+}
+
+#searchResults .gsc-above-wrapper-area {
+  display:none;
+}
+
+#searchResults .gsc-resultsbox-visible {
+  float:left;
+  width:720px;
+  margin-left:20px;
+}
+
+#searchResults .gsc-tabHeader {
+  padding: 3px 6px;
+  position:relative;
+  width:auto;
+  display:block;
+}
+
+#searchResults h2#searchTitle {
+  padding:0;
+  margin:5px 0;
+  border:none;
+}
+
+#searchResults h2#searchTitle em {
+  font-style:normal;
+  color:#33B5E5;
+}
+
+#searchResults .gsc-table-result {
+  margin:5px 0 10px 0;
+  background-color:transparent;
+}
+#searchResults .gs-web-image-box, .gs-promotion-image-box {
+  width:120px;
+}
+#searchResults .gs-web-image-box img.gs-image, .gs-promotion-image-box img.gs-promotion-image {
+  max-width:120px;
+}
+
+#searchResults .gsc-table-result .gsc-thumbnail {
+  padding:0 20px 0 0;
+}
+
+#searchResults td {
+  background-color:transparent;
+}
+
+#searchResults .gsc-expansionArea {
+  position:relative;
+}
+#searchResults .gsc-tabsArea .gsc-cursor-box {
+  width:200px;
+  padding:20px 0 0 1px;
+}
+#searchResults .gsc-cursor-page {
+  display:inline-block;
+  float:left;
+  margin:-1px 0 0 -1px;
+  padding:0;
+  height:27px;
+  width:27px;
+  text-align:center;
+  line-height:2;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhInactive,
+#searchResults .gsc-cursor-page {
+  text-decoration:none;
+  color:#258AAF;
+  border: solid 1px #DADADA;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhInactive:hover,
+#searchResults .gsc-cursor-page:hover {
+  border-color: #DBDBDB;
+  background-color: #F3F3F3;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#F9F9F9), to(#ECECEC));
+  background-image: -webkit-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -moz-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -ms-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -o-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: linear-gradient(top, #F9F9F9, #ECECEC);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+  color: #33B5E5;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhActive,
+#searchResults .gsc-tabHeader.gsc-tabhActive:hover,
+#searchResults .gsc-cursor-page.gsc-cursor-current-page,
+#searchResults .gsc-cursor-page.gsc-cursor-current-page:hover {
+  color:#fff;
+  background-color: #09C;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2FADDB), to(#09C));
+  background-image: -webkit-linear-gradient(top, #2FADDB, #09C);
+  background-image: -moz-linear-gradient(top, #2FADDB, #09C);
+  background-image: -ms-linear-gradient(top, #2FADDB, #09C);
+  background-image: -o-linear-gradient(top, #2FADDB, #09C);
+  background-image: linear-gradient(top, #2FADDB, #09C);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#09c');
+  border: 1px solid #3990AB;
+  z-index:100;
+}
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*********** PREVIOUSLY dac-styles.css ***************/
+
+
+
+
+
+::-webkit-selection,
+::-moz-selection,
+::selection {
+  background-color: #0099cc;
+  color: #fff; }
+
+#header {
+  border-bottom:0;
+}
+
+#header .wrap {
+  max-width:940px;
+  height:41px;
+  border-bottom:1px solid;
+  border-color: #ccc;
+  position:relative;
+}
+
+.about #header .wrap {
+  border-color: #9933CC;
+}
+
+.design #header .wrap {
+  border-color: #33b5e5;
+}
+
+.develop #header .wrap {
+  border-color: #F80;
+}
+
+.distribute #header .wrap {
+  border-color: #9C0;
+}
+
+.logo a {
+  width:123px;
+  float:left;
+}
+
+#header .logo {
+  margin-top: -6px;
+  margin-left: 0px;
+  margin-bottom:0px;
+  width: 160px;
+  padding-right:10px;
+}
+
+.search {
+  height:25px;
+  margin-top: -3px;
+  margin-bottom: 0px;
+}
+
+
+
+/* Quicknav */
+.btn-quicknav {
+  width:20px;
+  height:28px;
+  float:left;
+  margin-left:6px;
+  padding-right:10px;
+  position:relative;
+  cursor:pointer;
+  border-right:1px solid #CCC;
+}
+
+.btn-quicknav a {
+  zoom:1;
+  position:absolute;
+  top:13px;
+  left:5px;
+  display:block;
+  text-indent:-9999em;
+  width:10px;
+  height:5px;
+  background:url(../images/quicknav_arrow.png) no-repeat;
+}
+
+.btn-quicknav a.arrow-active {
+  background-position: 0 -5px;
+  display:none;
+}
+
+#header-wrap.quicknav a.arrow-inactive {
+  display:none;
+}
+
+.btn-quicknav.active a.arrow-active {
+  display:block;
+}
+
+.nav-x li {
+  display:block;
+  float:left;
+  margin-right:45px;
+  -webkit-transition: all 0.25s linear;
+      -moz-transition: all 0.25s linear;
+       -ms-transition: all 0.25s linear;
+        -o-transition: all 0.25s linear;
+           transition: all 0.25s linear;
+}
+
+#header-wrap.quicknav .nav-x li {
+  min-width:160px;
+  margin-right:20px;
+}
+
+#header-wrap.quicknav li.last {
+  margin-right:0px;
+}
+
+#quicknav {
+ float:none; 
+ clear:both;
+ margin-left:180px;
+ margin-top:-30px;
+ display:none;
+ overflow:hidden;
+}
+
+#header-wrap.quicknav #quicknav {
+
+}
+
+#quicknav ul {
+  margin:10px 0;
+  padding:0;
+}
+
+#quicknav ul li.design {
+  border-top:1px solid #33b5e5;
+}
+
+#quicknav ul li.develop {
+  border-top:1px solid #FF8800;
+}
+
+#quicknav ul li.distribute {
+  border-top:1px solid #99cc00;
+}
+
+#quicknav ul li {
+  display:block;
+  float:left;
+  margin:0 20px 0 0;
+  min-width:140px;
+}
+
+#quicknav ul li.last {
+  margin-right:0px;
+}
+
+#quicknav ul li ul li {
+  float:none;
+}
+
+#quicknav ul li ul li a {
+  color:#222;
+}
+
+#quicknav ul li li ul,
+#quicknav ul li li ul li {
+  margin:0;
+}
+
+#quicknav ul li li ul li:before {
+  content:"\21B3";
+}
+
+#header-wrap {
+   -webkit-transition: all 0.25s ease-out;
+      -moz-transition: all 0.25s ease-out;
+       -ms-transition: all 0.25s ease-out;
+        -o-transition: all 0.25s ease-out;
+           transition: all 0.25s ease-out;
+
+}
+
+#header-wrap.quicknav {
+  height:170px;
+  
+}
+
+/* SEARCH AND MORE */
+.search {
+  position: absolute;
+  width: 50px;
+  height:28px;
+  display: block;
+  margin-top:-3px;
+  margin-bottom:7px;
+  overflow:hidden;
+  z-index:100;
+  right:54px;
+  -webkit-transition: width 0.4s ease;
+     -moz-transition: width 0.4s ease;
+       -o-transition: width 0.4s ease;
+          transition: width 0.4s ease;
+}
+
+.search #search-btn {
+  width:50px;
+  height:28px;
+  background:url(../images/icon_search.png) no-repeat;
+  float:left;
+}
+
+.search-inner {
+  width:245px;
+}
+
+.search:hover, .search.active {
+  width:245px;
+}
+
+.search .bottom, .search .left, .search .right {
+	position: absolute;
+	background-color: #a2a2a2
+}
+
+.search .bottom {
+	width: 214px;
+	height: 1px;
+	top: 24px;
+	left: 0
+}
+
+.search .left, .search .right {	
+	height: 5px;
+	width: 1px
+}
+
+.search .left {
+  top: 22px;
+  left: 56px;
+  background-color:#CCC;
+}
+
+.search .right {
+  top: 22px;
+  left: 238px;
+  background-color:#CCC;
+}
+
+.search form {
+	margin-top: 2px;
+	width: 162px;
+	float:left;
+}
+
+.search form input {
+	color: #2f2f2f;
+	font-size: 0.95em;
+	width: 178px;  
+	border: none;
+	margin-left: 6px;  
+	z-index: 1500;  
+  position: relative;
+	background-color: transparent;
+	border-bottom:1px solid #CCC;
+	padding:0 0 0 4px;
+	outline:none;
+	height:24px;
+}
+
+.search:hover form input {
+  border-bottom:1px solid #33B5E5;
+}
+
+.search:hover .bottom, .search:hover .left, .search:hover .right {
+	background-color: #33b5e5;
+}
+
+.search:hover #search-btn {
+	background-position: 0 -28px
+}
+
+.search form input:focus {
+	color: #222;
+	font-weight: bold
+}
+
+.moremenu {
+  float: right;
+	position: relative;
+	width: 50px;
+	height:28px;
+  display: block;
+  margin-top:-3px;
+  margin-bottom:7px;
+  overflow:hidden;
+  -webkit-transition: width 0.25s ease;
+     -moz-transition: width 0.25s ease;
+       -o-transition: width 0.25s ease;
+          transition: width 0.25s ease;
+}
+
+.moremenu #more-btn {
+  width:40px;
+  height:28px;
+  background:url(../images/icon_more.png) no-repeat;
+  border-left:1px solid #CCC;
+  float:left;
+  cursor:pointer;
+}
+
+.moremenu:hover #more-btn {
+  background-position:0 -28px;
+}
+
+.morehover {
+  position:absolute;
+  right:6px;
+  top:-9px;
+  width:40px;
+  height:35px;
+  z-index:99;
+  overflow:hidden;
+
+  -webkit-opacity:0;
+     -moz-opacity:0;
+       -o-opacity:0;
+          opacity:0;
+
+  -webkit-transform-origin:100% 0%;
+     -moz-transform-origin:100% 0%; 
+       -o-transform-origin:100% 0%;
+          transform-origin:100% 0%;
+  
+  -webkit-transition-property: -webkit-opacity;
+  -webkit-transition-duration: .25s;
+  -webkit-transition-timing-function:ease;
+
+  -moz-transition-property: -webkit-opacity;
+  -moz-transition-duration: .25s;
+  -moz-transition-timing-function:ease;
+
+  -o-transition-property: -webkit-opacity;
+  -o-transition-duration: .25s;
+  -o-transition-timing-function:ease;
+  
+  -transition-property: -webkit-opacity;
+  -transition-duration: .25s;
+  -transition-timing-function:ease;
+}
+
+.morehover:hover {
+  opacity:1;
+  height:345px;
+  width:268px;
+  -webkit-transition-property:height,  -webkit-opacity;
+}
+
+.morehover .top {
+  width:268px;
+  height:39px;
+  background:url(../images/more_top.png) no-repeat;
+}
+
+.morehover .mid {
+  width:228px;
+  background:url(../images/more_mid.png) repeat-y;
+  padding:10px 20px 10px 20px;
+}
+
+.morehover .mid .header {
+  border-bottom:1px solid #ccc;
+  font-weight:bold;
+}
+
+.morehover .bottom {
+  width:268px;
+  height:6px;
+  background:url(../images/more_bottom.png) no-repeat;
+}
+
+.morehover ul {
+  margin:10px 10px 20px 0;
+}
+
+.morehover ul li {
+  list-style:none;
+}
+
+.morehover ul li.active a,
+.morehover ul li.active a:hover {
+  color:#222 !important;
+}
+
+.morehover ul li.active img {
+  margin-right:4px;
+}
+
+
+
+
+/* MARQUEE */
+.slideshow-container {
+	width:100%;
+	overflow:hidden;
+	position:relative;
+}
+.slideshow-container .slideshow-prev {
+	position:absolute;
+	top:50%;
+	left:0px;
+	margin-top:-36px;
+	z-index:99;
+}
+.slideshow-container .slideshow-next {
+	position:absolute;
+	top:50%;
+	margin-top:-36px;
+	z-index:99;
+	right:0px;
+}
+
+.slideshow-container .pagination {
+	position:absolute;
+	bottom:20px;
+	width:100%;
+	text-align:center;
+	z-index:99;
+}
+.slideshow-container .pagination ul {
+	margin:0;
+}
+.slideshow-container .pagination ul li{
+	display: inline-block;
+	width:12px;
+	height:12px;
+	text-indent:-8000px;
+	list-style:none;
+	margin: 0 2px;
+	border-radius:6px;
+	background-color:#ccc;
+	cursor:pointer;
+        -webkit-transition:color .5s ease-in;  
+        -moz-transition:color .5s ease-in;  
+        -o-transition:color .5s ease-in;  
+        transition:color .5s ease-in;
+}
+.slideshow-container .pagination ul li:hover {
+	background-color:#999;
+}
+.slideshow-container .pagination ul li.active {
+	background-color:#33b5e5;
+}
+.slideshow-container .pagination ul li.active:hover {
+	background-color:#33b5e5;
+}
+.slideshow-container ul li {
+	display:inline;
+	list-style:none;
+}
+
+
+
+
+a.download-sdk {
+    float:right;
+    margin:-10px 0;
+    height:30px;
+    padding-top:4px;
+    padding-bottom:0px;
+}
+
+#nav-x {
+  padding-top: 14px;
+}
+
+#nav-x .wrap,
+#searchResults.wrap {
+    max-width:940px;
+    border-bottom:1px solid #CCC;
+    min-height:34px;
+    
+}
+
+
+.nav-x {
+    margin-left:0;
+    margin-bottom:0;
+}
+
+
+
+
+
+
+
+
+
+
+/*
+ * CSS Styles that are needed by jScrollPane for it to operate correctly.
+ */
+
+.jspContainer {
+  overflow: hidden;
+  position: relative;
+}
+
+.jspPane {
+  position: absolute;
+  overflow: hidden;
+  width:auto !important; /* to avoid cut-off api names in reference in horiz scroll */
+}
+
+.jspVerticalBar {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 4px;
+  height: 100%;
+  background: #f5f5f5;
+}
+
+.jspHorizontalBar {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 4px;
+  background: #f5f5f5;
+}
+
+.jspVerticalBar *,
+.jspHorizontalBar * {
+  margin: 0;
+  padding: 0;
+}
+.jspCap {
+  display: block;
+}
+
+.jspVerticalBar .jspCap {
+  height: 4px;
+}
+
+.jspHorizontalBar .jspCap {
+  width: 0;
+  height: 100%;
+}
+
+.jspHorizontalBar .jspCap {
+  float: left;
+}
+
+.jspTrack {
+  position: relative;
+}
+
+.jspDrag {
+  background: #bbb;
+  position: relative;
+  top: 0;
+  left: 0;
+  cursor: pointer;
+}
+
+.jspDrag:hover,
+.jspDrag:active {
+  border-color: #09c;
+  background-color: #4cadcb;
+  background-image: -webkit-gradient(linear, left top, right top, from(#5dbcd9), to(#4cadcb));
+  background-image: -webkit-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -moz-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -ms-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -o-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: linear-gradient(left, #5dbcd9, #4cadcb);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5dbcd9', EndColorStr='#4cadcb');	
+}
+
+.jspHorizontalBar .jspTrack,
+.jspHorizontalBar .jspDrag {
+  float: left;
+  height: 100%;
+}
+
+.jspArrow {
+  background: #999;
+  text-indent: -20000px;
+  display: block;
+  cursor: pointer;
+}
+
+.jspArrow.jspDisabled {
+  cursor: default;
+  background: #ccc;
+}
+
+.jspVerticalBar .jspArrow {
+  height: 16px;
+}
+
+.jspHorizontalBar .jspArrow {
+  width: 16px;
+  float: left;
+  height: 100%;
+}
+
+.jspVerticalBar .jspArrow:focus {
+  outline: none;
+}
+
+.jspCorner {
+  float: left;
+  height: 100%;
+}
+
+/* Yuk! CSS Hack for IE6 3 pixel bug :( */
+* html .jspCorner {
+  margin: 0 -3px 0 0;
+}
+/******* end of jscrollpane *********/
+
+
+
+
+
+/************ DEVELOP HOMEPAGE ******************/
+
+/* Slideshow */
+.slideshow-develop {
+  height: 300px;
+  width: 940px;
+  position: relative;
+  overflow:hidden;
+}
+.slideshow-develop .frame {
+  width: 940px;
+  height: 300px;
+}
+.slideshow-develop img.play {
+  width:350px;
+  margin:20px 0 0 90px;
+  -webkit-transform: perspective(800px ) rotateY( 35deg );
+  box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+  -moz-box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+  -webkit-box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+}
+.slideshow-develop img.play.no-shadow {
+    box-shadow: none;
+    -moz-box-shadow: none;
+    -webkit-box-shadow: none;
+}
+.slideshow-develop img.play.no-transform {
+  -webkit-transform: none;
+}
+.slideshow-develop a.slideshow-next {
+  background: url(../images/arrow-right-develop.png);
+}
+.slideshow-develop a.slideshow-prev {
+  background: url(../images/arrow-left-develop.png);
+}
+.slideshow-develop .content-right {
+  float: left;
+}
+.slideshow-develop .content-right p.title-intro {
+  position:absolute;
+  margin:0;
+}
+.slideshow-develop .content-right h2 {
+  padding:0;
+  margin-bottom:10px;
+  border:none;
+}
+.slideshow-develop .item {
+  height: 300px;
+  width: 940px;
+}
+.slideshow-develop .pagination ul li.active {
+  background-color: #F80;
+}
+.slideshow-develop .pagination ul li.active:hover {
+  background-color: #F80;
+}
+
+/* Feeds */
+.feed ul {
+  margin: 0;
+}
+.feed .feed-nav {
+  height: 25px;
+  border-bottom: 1px solid #CCC;
+}
+.feed .feed-nav li {
+  list-style: none;
+  float: left;
+  margin-right: 25px;
+  cursor: pointer;
+}
+.feed .feed-nav li.active {
+  color: #000;
+  border-bottom: 4px solid #F80;
+}
+.feed .feed-container {
+  overflow: hidden;
+  width: 460px;
+}
+.feed .feed-container .feed-frame {
+  width: 1000px;
+}
+.feed .feed-container .feed-frame ul {
+  float: left;
+  width:460px;
+}
+.feed .feed-container .feed-frame ul ul {
+  float: none;
+  margin:10px 0 0 30px;
+}
+.feed .feed-container .feed-frame li {
+  list-style: none;
+  margin: 20px 0 20px 0;
+  width: 460px;
+  height:93px;
+}
+.feed .feed-container .feed-frame li.playlist {
+  height:auto;
+}
+.feed .feed-container .feed-frame li.playlist a {
+  height:93px;
+  display:block;
+}
+.feed .feed-container .feed-frame li.more {
+  height:20px;
+  margin:10px 0 5px 5px;
+}
+.feed .feed-container .feed-frame li.more a {
+  height:inherit;
+}
+.feed .feed-container .feed-frame li.playlist-video {
+  list-style: none;
+  margin: 0;
+  width: 460px;
+  height:55px;
+  font-size:12px;
+}
+.feed .feed-container .feed-frame li.playlist-video a {
+  height:45px;
+  padding:5px;
+}
+.feed .feed-container .feed-frame li.playlist-video h5 {
+  font-size:12px;
+  line-height:13px;
+  margin:0;
+}
+.feed .feed-container .feed-frame li.playlist-video p {
+  margin:5px 0 0;
+  line-height:15px;
+}
+.feed-container .feed-frame div.feed-image {
+  float: left;
+  border: 1px solid #999;
+  margin:0 20px 0 0;
+  width:122px;
+  height:92px;
+  background:url('../images/blog-default.png') no-repeat 0 0;
+  background-size:180px;
+}
+#jd-content .feed .feed-container .feed-frame li img {
+  float: left;
+  border: 1px solid #999;
+  margin:0 20px 0 0;
+  width:122px;
+  height:92px;
+}
+#jd-content .feed .feed-container .feed-frame li.playlist-video img {
+  width:inherit;
+  height:inherit;
+}
+
+.feed .feed-container .feed-frame li a,
+.feed .feed-container .feed-frame li a:active {
+  color:#555 !important;
+}
+
+.feed .feed-container .feed-frame li a:hover,
+.feed .feed-container .feed-frame li a:hover * {
+  color:#7AA1B0 !important;
+}
+
+/* Video player */
+#player-wrapper {
+  display:none;
+  margin: -1px auto 0;
+  position: relative;
+  width: 940px;
+  height: 0px;
+}
+#player-frame {
+  background: #EFEFEF;
+  border: 1px solid #CCC;
+  padding: 0px 207px;
+  z-index: 10; /* stay above marque, but below search suggestions */
+  width: 525px;
+  height: 330px;
+  position: relative;
+}
+
+
+
+/************ DISTRIBUTE HOMEPAGE ***************/
+
+.marquee {
+  width: 760px;
+}
+.marquee .main-img {
+  float: left;
+  margin-top: 20px;
+  width: 490px;
+}
+.marquee .copy {
+  width: 270px;
+  float: left;
+  margin-top: 30px;
+}
+.distribute-features {
+  margin: 0;
+}
+.distribute-features ul {
+  margin: 0;
+}
+.distribute-features ul li {
+  list-style: none;
+  float: left;
+  border-top: 1px solid #9C0;
+  width: 220px;
+  margin-right: 50px;
+}
+.distribute-features ul li.last {
+  margin-right: 0px;
+}
+
+
+/************ DEVELOP TOPIC CONTAINERS ************/
+
+.landing-banner,
+.landing-docs {
+  margin:20px 0 0;
+}
+.landing-banner {
+  height:280px;
+}
+.landing-banner .col-6:first-child,
+.landing-docs .col-6:first-child {
+  margin-left:0;
+}
+.landing-banner .col-6:last-child,
+.landing-docs .col-6:last-child {
+  margin-right:0;
+}
+
+.landing-banner h1 {
+  margin-top:0;
+}
+.landing-docs h3 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:1px solid #CCC;
+  margin:0 0 20px;
+}
+.landing-docs a {
+  color:#333 !important;
+}
+.landing-docs a:hover,
+.landing-docs a:hover * {
+  color:#7AA1B0 !important
+}
+
+.plusone {
+  float:right;
+}
\ No newline at end of file
diff --git a/docs/html/guide/google/gcm/client-javadoc/deprecated-list.html b/docs/html/guide/google/gcm/client-javadoc/deprecated-list.html
index ebdcc26..6b86bfe 100644
--- a/docs/html/guide/google/gcm/client-javadoc/deprecated-list.html
+++ b/docs/html/guide/google/gcm/client-javadoc/deprecated-list.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 Deprecated List
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/help-doc.html b/docs/html/guide/google/gcm/client-javadoc/help-doc.html
index 0dc47eb..ffd1f77 100644
--- a/docs/html/guide/google/gcm/client-javadoc/help-doc.html
+++ b/docs/html/guide/google/gcm/client-javadoc/help-doc.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 API Help
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/client-javadoc/index-all.html b/docs/html/guide/google/gcm/client-javadoc/index-all.html
index 43b8e4e..74e6095 100644
--- a/docs/html/guide/google/gcm/client-javadoc/index-all.html
+++ b/docs/html/guide/google/gcm/client-javadoc/index-all.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 Index
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="./stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="./default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -94,6 +94,10 @@
 <DT><A HREF="./com/google/android/gcm/GCMConstants.html#DEFAULT_INTENT_SERVICE_CLASS_NAME"><B>DEFAULT_INTENT_SERVICE_CLASS_NAME</B></A> - 
 Static variable in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMConstants.html" title="class in com.google.android.gcm">GCMConstants</A>
 <DD>&nbsp;
+<DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#DEFAULT_ON_SERVER_LIFESPAN_MS"><B>DEFAULT_ON_SERVER_LIFESPAN_MS</B></A> - 
+Static variable in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
+<DD>Default lifespan (7 days) of the <A HREF="./com/google/android/gcm/GCMRegistrar.html#isRegisteredOnServer(Context)"><CODE>isRegisteredOnServer(Context)</CODE></A>
+ flag until it is considered expired.
 </DL>
 <HR>
 <A NAME="_E_"><!-- --></A><H2>
@@ -150,10 +154,13 @@
 <B>G</B></H2>
 <DL>
 <DT><A HREF="./com/google/android/gcm/GCMBaseIntentService.html" title="class in com.google.android.gcm"><B>GCMBaseIntentService</B></A> - Class in <A HREF="./com/google/android/gcm/package-summary.html">com.google.android.gcm</A><DD>Skeleton for application-specific <CODE>IntentService</CODE>s responsible for
- handling communication from Google Cloud Messaging service.<DT><A HREF="./com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService(java.lang.String)"><B>GCMBaseIntentService(String)</B></A> - 
+ handling communication from Google Cloud Messaging service.<DT><A HREF="./com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService()"><B>GCMBaseIntentService()</B></A> - 
 Constructor for class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMBaseIntentService.html" title="class in com.google.android.gcm">GCMBaseIntentService</A>
-<DD>Subclasses must create a public no-arg constructor and pass the
- sender id to be used for registration.
+<DD>Constructor that does not set a sender id, useful when the sender id
+ is context-specific.
+<DT><A HREF="./com/google/android/gcm/GCMBaseIntentService.html#GCMBaseIntentService(java.lang.String...)"><B>GCMBaseIntentService(String...)</B></A> - 
+Constructor for class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMBaseIntentService.html" title="class in com.google.android.gcm">GCMBaseIntentService</A>
+<DD>Constructor used when the sender id(s) is fixed.
 <DT><A HREF="./com/google/android/gcm/GCMBroadcastReceiver.html" title="class in com.google.android.gcm"><B>GCMBroadcastReceiver</B></A> - Class in <A HREF="./com/google/android/gcm/package-summary.html">com.google.android.gcm</A><DD><CODE>BroadcastReceiver</CODE> that receives GCM messages and delivers them to
  an application-specific <A HREF="./com/google/android/gcm/GCMBaseIntentService.html" title="class in com.google.android.gcm"><CODE>GCMBaseIntentService</CODE></A> subclass.<DT><A HREF="./com/google/android/gcm/GCMBroadcastReceiver.html#GCMBroadcastReceiver()"><B>GCMBroadcastReceiver()</B></A> - 
 Constructor for class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMBroadcastReceiver.html" title="class in com.google.android.gcm">GCMBroadcastReceiver</A>
@@ -161,9 +168,16 @@
 <DT><A HREF="./com/google/android/gcm/GCMConstants.html" title="class in com.google.android.gcm"><B>GCMConstants</B></A> - Class in <A HREF="./com/google/android/gcm/package-summary.html">com.google.android.gcm</A><DD>Constants used by the GCM library.<DT><A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm"><B>GCMRegistrar</B></A> - Class in <A HREF="./com/google/android/gcm/package-summary.html">com.google.android.gcm</A><DD>Utilities for device registration.<DT><A HREF="./com/google/android/gcm/GCMBroadcastReceiver.html#getGCMIntentServiceClassName(Context)"><B>getGCMIntentServiceClassName(Context)</B></A> - 
 Method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMBroadcastReceiver.html" title="class in com.google.android.gcm">GCMBroadcastReceiver</A>
 <DD>Gets the class name of the intent service that will handle GCM messages.
+<DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#getRegisterOnServerLifespan(Context)"><B>getRegisterOnServerLifespan(Context)</B></A> - 
+Static method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
+<DD>Gets how long (in milliseconds) the <A HREF="./com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ property is valid.
 <DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#getRegistrationId(Context)"><B>getRegistrationId(Context)</B></A> - 
 Static method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
 <DD>Gets the current registration id for application on GCM service.
+<DT><A HREF="./com/google/android/gcm/GCMBaseIntentService.html#getSenderIds(Context)"><B>getSenderIds(Context)</B></A> - 
+Method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMBaseIntentService.html" title="class in com.google.android.gcm">GCMBaseIntentService</A>
+<DD>Gets the sender ids.
 </DL>
 <HR>
 <A NAME="_I_"><!-- --></A><H2>
@@ -191,7 +205,8 @@
  service.
 <DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#isRegisteredOnServer(Context)"><B>isRegisteredOnServer(Context)</B></A> - 
 Static method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
-<DD>Checks whether the device was successfully registered in the server side.
+<DD>Checks whether the device was successfully registered in the server side,
+ as set by <A HREF="./com/google/android/gcm/GCMRegistrar.html#setRegisteredOnServer(Context, boolean)"><CODE>setRegisteredOnServer(Context, boolean)</CODE></A>.
 </DL>
 <HR>
 <A NAME="_O_"><!-- --></A><H2>
@@ -249,6 +264,10 @@
 <DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#setRegisteredOnServer(Context, boolean)"><B>setRegisteredOnServer(Context, boolean)</B></A> - 
 Static method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
 <DD>Sets whether the device was successfully registered in the server side.
+<DT><A HREF="./com/google/android/gcm/GCMRegistrar.html#setRegisterOnServerLifespan(Context, long)"><B>setRegisterOnServerLifespan(Context, long)</B></A> - 
+Static method in class com.google.android.gcm.<A HREF="./com/google/android/gcm/GCMRegistrar.html" title="class in com.google.android.gcm">GCMRegistrar</A>
+<DD>Sets how long (in milliseconds) the <A HREF="./com/google/android/gcm/GCMRegistrar.html#isRegistered(Context)"><CODE>isRegistered(Context)</CODE></A>
+ flag is valid.
 </DL>
 <HR>
 <A NAME="_T_"><!-- --></A><H2>
diff --git a/docs/html/guide/google/gcm/client-javadoc/index.html b/docs/html/guide/google/gcm/client-javadoc/index.html
index a7753f7..26e57f6 100644
--- a/docs/html/guide/google/gcm/client-javadoc/index.html
+++ b/docs/html/guide/google/gcm/client-javadoc/index.html
@@ -2,12 +2,10 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc on Thu Jun 21 12:06:25 PDT 2012-->
+<!-- Generated by javadoc on Mon Jul 16 14:13:37 PDT 2012-->
 <TITLE>
 Generated Documentation (Untitled)
 </TITLE>
-
-
 <SCRIPT type="text/javascript">
     targetPage = "" + window.location.search;
     if (targetPage != "" && targetPage != "undefined")
diff --git a/docs/html/guide/google/gcm/client-javadoc/overview-tree.html b/docs/html/guide/google/gcm/client-javadoc/overview-tree.html
index 6ea6fb3..c9076f1 100644
--- a/docs/html/guide/google/gcm/client-javadoc/overview-tree.html
+++ b/docs/html/guide/google/gcm/client-javadoc/overview-tree.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:06:25 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:13:37 PDT 2012 -->
 <TITLE>
 Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/demo.jd b/docs/html/guide/google/gcm/demo.jd
index 4c56373..d66cbbc 100644
--- a/docs/html/guide/google/gcm/demo.jd
+++ b/docs/html/guide/google/gcm/demo.jd
@@ -43,6 +43,9 @@
   <li><a href="{@docRoot}guide/google/gcm/client-javadoc/index.html">Client Reference</a></li>
   <li><a href="{@docRoot}guide/google/gcm/server-javadoc/index.html">Server Reference</a></li>
 </ul>
+
+<p>The sections below describe how to download the demo code and helper libraries from the SDK Manager. The demo code and helper libraries are also available at the <a href="http://code.google.com/p/gcm">open source site</a>.
+
 <h2 id="requirements">Requirements</h2>
 <p>For the web server:</p>
 <ul>
@@ -75,6 +78,8 @@
     
     
     <p>This creates a <code>gcm</code> directory under <code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these subdirectories: <code>gcm-client</code>, <code>gcm-server</code>, <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
+
+<p class="note"><strong>Note:</strong> If you don't see <strong>Extras &gt; Google Cloud Messaging for Android Library</strong> in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.</p>
   </li>
 
   <li>In a text editor, edit the <code>samples/gcm-demo-server/WebContent/WEB-INF/classes/api.key</code> and replace the existing text with the API key obtained above.</li>
diff --git a/docs/html/guide/google/gcm/gcm.jd b/docs/html/guide/google/gcm/gcm.jd
index 3884244..79edb9f 100644
--- a/docs/html/guide/google/gcm/gcm.jd
+++ b/docs/html/guide/google/gcm/gcm.jd
@@ -844,12 +844,14 @@
 <dt id="missing_reg"><strong>Missing Registration ID</strong></dt>
 <dd>Check that the request contains a registration ID (either in the <code>registration_id</code> parameter in a plain text message, or in the <code>registration_ids</code> field in JSON). 
 <br/>Happens when error code is <code>MissingRegistration</code>.</dd>
+
 <dt id="invalid_reg"><strong>Invalid Registration ID</strong></dt>
 <dd>Check the formatting of the registration ID that you pass to the server. Make sure it matches the registration ID the phone receives in the <code>com.google.android.c2dm.intent.REGISTRATION</code> intent and that you're not truncating it or adding additional characters. 
 <br/>Happens when error code is <code>InvalidRegistration</code>.</dd>
 <dt id="mismatched_sender"><strong>Mismatched Sender</strong></dt>
 <dd>A registration ID is tied to a certain group of senders. When an application registers for GCM usage, it must specify which senders are allowed to send messages. Make sure you're using one of those when trying to send messages to the device. If you switch to a different sender, the existing registration IDs won't work. 
 Happens when error code is <code>MismatchSenderId</code>.</dd>
+
 <dt id="unreg_device"><strong>Unregistered Device</strong></dt>
 <dd>An existing registration ID may cease to be valid in a number of scenarios, including:
 <ul>
@@ -860,25 +862,64 @@
 For all these cases, you should remove this registration ID from the 3rd-party server and stop using it to send 
 messages. 
 <br/>Happens when error code is <code>NotRegistered</code>.</dd>
+
   <dt id="big_msg"><strong>Message Too Big</strong></dt>
   <dd>The total size of the payload data that is included in a message can't exceed 4096 bytes. Note that this includes both the size of the keys as well as the values. 
 <br/>Happens when error code is <code>MessageTooBig</code>.</dd>
-  <dt id="auth_error"><strong>Authentication Error</strong></dt>
-  <dd>The sender account that you're trying to use to send a message couldn't be authenticated. Possible causes are: request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected).  The exact failure reason is described in the response and the problem should be addressed before the request can be retried. Possible causes are: authorization header missing or with invalid syntax, invalid project ID sent as key, key valid but with GCM service disabled, and so on. Check that the Sender Auth Token you're sending inside the <code>Authorization</code> header is the correct API key associated with your project. 
-<br/>Happens when the HTTP status code is 401.
-  </dd>
-  <dt id="internal_error"><strong>Internal Server Error/Timeout</strong></dt>
-  <dd>The server encountered an error while trying to process the request or couldn't finish in time. You can retry the same request, but you MUST obey the following requirements:  
-<ul>
-  <li>Honor the <code>Retry-After</code> header if it's included in the response from the GCM server.</li>
-  <li>Implement exponential back-off in your retry mechanism. This means an exponentially increasing delay after each failed retry (e.g. if you waited one second before the first retry, wait at least two second before the next one, then 4 seconds and so on). If you're sending multiple messages, delay each one independently by an additional random amount to avoid issuing a new request for all messages at the same time.</li>
-</ul>
-Senders that cause problems risk being blacklisted.
-<br/>Happens when the HTTP status code is 500 or 503, or when the <code>error</code> field of a JSON object in the <code>results</code> array is <code>InternalServerError</code> or <code>Unavailable</code>.</dd>
 
 <dt id="ttl_error"><strong>Invalid Time To Live</strong></dt>
   <dd>The value for the Time to Live field must be an integer representing a duration in seconds between 0 and 2,419,200 (4 weeks). Happens when error code is <code>InvalidTtl</code>.
 </dd>
+
+  <dt id="auth_error"><strong>Authentication Error</strong></dt>
+  <dd>The sender account that you're trying to use to send a message couldn't be authenticated. Possible causes are: <ul>
+<li>Authorization header missing or with invalid syntax.</li>
+<li>Invalid project ID sent as key.</li>
+<li>Key valid but with GCM service disabled.</li>
+<li>Request originated from a server not whitelisted in the Server Key IPs.</li>
+
+</ul>
+Check that the token you're sending inside the <code>Authorization</code> header is the correct API key associated with your project.<br/>
+
+Happens when the HTTP status code is 401.
+
+  <dt id="timeout"><strong>Timeout</strong></dt>
+
+<dd>The server couldn't process the request in time. You should retry the
+same request, but you MUST obey the following requirements:
+
+<ul>
+
+<li>Honor the <code>Retry-After</code> header if it's included in the response from the GCM server.</li>
+        
+        
+<li>Implement exponential back-off in your retry mechanism. This means an
+exponentially increasing delay after each failed retry (e.g. if you waited one
+second before the first retry, wait at least two second before the next one,
+then 4 seconds and so on). If you're sending multiple messages, delay each one
+independently by an additional random amount to avoid issuing a new request for
+all messages at the same time.</li>
+    
+
+Senders that cause problems risk being blacklisted. 
+<br />
+Happens when the HTTP status code is 503, or when the <code>error</code> field of a JSON object in the results array is <code>Unavailable</code>.
+</dd>
+
+<dt id="internal_error"><strong>Internal Server Error</strong></dt>
+
+<dd>
+The server encountered an error while trying to process the request. You
+could retry the same request (obeying the requirements listed in the <strong>Timeout</strong>
+section), but if the error persists, please report the problem in the <a href="https://groups.google.com/forum/?fromgroups#!forum/android-gcm">android-gcm group</a>.
+<br /> 
+Senders that cause problems risk being blacklisted. 
+<br />
+Happens when the HTTP status code is 500, or when the <code>error</code> field of a JSON
+object in the results array is <code>InternalServerError</code>.
+</dd>
+
+
 </dl>
 <h4>Example responses</h4>
 <p>This section shows a few examples of responses indicating messages that were processed successfully. See <a href="#example-requests">Example requests</a> for the requests these responses are based on.</p>
diff --git a/docs/html/guide/google/gcm/gs.jd b/docs/html/guide/google/gcm/gs.jd
index 8f05d30..6f8598f 100644
--- a/docs/html/guide/google/gcm/gs.jd
+++ b/docs/html/guide/google/gcm/gs.jd
@@ -63,7 +63,7 @@
 </div>
 </div>
 
-  <li>Click  <strong>Create new Server key</strong>. The following screen appears:</li><br />
+  <li>Click  <strong>Create new Server key</strong>. Either a server key or a browser key should work. The advantage to using a server key is that it allows you to whitelist IP addresses. The following screen appears:</li><br />
 
 <div style="width:408px;margin:1.5em;">
 <div style="width:410px;border:1px solid #DDD;">
@@ -86,6 +86,9 @@
 
 <h2 id="libs">Install the Helper Libraries</h2>
 <p>To perform the steps described in the following sections, you must first install the helper libraries (reference: <a href="{@docRoot}guide/google/gcm/client-javadoc/index.html">client</a> and <a href="{@docRoot}guide/google/gcm/server-javadoc/index.html">server</a>). From the SDK Manager, install <strong>Extras &gt; Google Cloud Messaging for Android Library</strong>. This creates a <code>gcm</code> directory under <code><em>YOUR_SDK_ROOT</em>/extras/google/</code> containing these subdirectories: <code>gcm-client</code>, <code>gcm-server</code>, <code>samples/gcm-demo-client</code>, <code>samples/gcm-demo-server</code>, and <code>samples/gcm-demo-appengine</code>.</p>
+
+<p class="note"><strong>Note:</strong> If you don't see <strong>Extras &gt; Google Cloud Messaging for Android Library</strong> in the SDK Manager, make sure you are running version 20 or higher. Be sure to restart the SDK Manager after updating it.</p>
+
 <h2 id="android-app">Writing the Android Application</h2>
 <p>This section describes the steps involved in writing an Android application that uses GCM.</p>
 <h4>Step 1: Copy the gcm.jar file into your application classpath</h4>
@@ -175,14 +178,14 @@
   <li>Create a servlet (or other server-side mechanism) that can be used by the Android application to send the registration ID received by GCM . The application might also need to send other information&mdash;such as the user's email address or username&mdash;so that the server can associate the registration ID with the user owning the device.</li>
   <li>Similarly, create a servlet used to unregister registration IDs.<br>
     </li>
-  <li>When the server needs to send a message to the device, it can use the <code>com.google.android.gcm.server.Sender</code> helper class from the GCM library. For example:</li>
+<li>When the server needs to send a message to the registration ID, it can use the <code>com.google.android.gcm.server.Sender</code> helper class from the GCM library. For example:</li>
 </ol>
 
 <pre class="prettyprint pretty-java">import com.google.android.gcm.server.*;
 
 Sender sender = new Sender(myApiKey);
-Message message = new Message.Builder(regId).build();
-Result result = sender.send(message, 5);</pre>
+Message message = new Message.Builder().build();
+MulticastResult result = sender.send(message, devices, 5);</pre>
 
 <p> The snippet above does the following:
 <ul>
diff --git a/docs/html/guide/google/gcm/server-javadoc/allclasses-frame.html b/docs/html/guide/google/gcm/server-javadoc/allclasses-frame.html
index d2fe43d..cf7dc28 100644
--- a/docs/html/guide/google/gcm/server-javadoc/allclasses-frame.html
+++ b/docs/html/guide/google/gcm/server-javadoc/allclasses-frame.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/server-javadoc/allclasses-noframe.html b/docs/html/guide/google/gcm/server-javadoc/allclasses-noframe.html
index 0f0dc96..299085c 100644
--- a/docs/html/guide/google/gcm/server-javadoc/allclasses-noframe.html
+++ b/docs/html/guide/google/gcm/server-javadoc/allclasses-noframe.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 All Classes
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Constants.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Constants.html
index 09ac011..7384dfd 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Constants.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Constants.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:56 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:09 PDT 2012 -->
 <TITLE>
 Constants
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -125,6 +125,15 @@
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/google/android/gcm/server/Constants.html#ERROR_INTERNAL_SERVER_ERROR">ERROR_INTERNAL_SERVER_ERROR</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A particular message could not be sent because the GCM servers encountered
+ an error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../../../com/google/android/gcm/server/Constants.html#ERROR_INVALID_REGISTRATION">ERROR_INVALID_REGISTRATION</A></B></CODE>
 
 <BR>
@@ -133,6 +142,14 @@
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
 <CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../../com/google/android/gcm/server/Constants.html#ERROR_INVALID_TTL">ERROR_INVALID_TTL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Time to Live value passed is less than zero or more than maximum.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
 <TD><CODE><B><A HREF="../../../../../com/google/android/gcm/server/Constants.html#ERROR_MESSAGE_TOO_BIG">ERROR_MESSAGE_TOO_BIG</A></B></CODE>
 
 <BR>
@@ -185,8 +202,8 @@
 <TD><CODE><B><A HREF="../../../../../com/google/android/gcm/server/Constants.html#ERROR_UNAVAILABLE">ERROR_UNAVAILABLE</A></B></CODE>
 
 <BR>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Used to indicate that a particular message could not be sent because
- the GCM servers were not available.</TD>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A particular message could not be sent because the GCM servers were not
+ available.</TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
 <TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
@@ -547,15 +564,41 @@
 <PRE>
 public static final java.lang.String <B>ERROR_UNAVAILABLE</B></PRE>
 <DL>
-<DD>Used to indicate that a particular message could not be sent because
- the GCM servers were not available. Used only on JSON requests, as in
- plain text requests unavailability is indicated by a 503 response.
+<DD>A particular message could not be sent because the GCM servers were not
+ available. Used only on JSON requests, as in plain text requests
+ unavailability is indicated by a 503 response.
 <P>
 <DL>
 <DT><B>See Also:</B><DD><A HREF="../../../../../constant-values.html#com.google.android.gcm.server.Constants.ERROR_UNAVAILABLE">Constant Field Values</A></DL>
 </DL>
 <HR>
 
+<A NAME="ERROR_INTERNAL_SERVER_ERROR"><!-- --></A><H3>
+ERROR_INTERNAL_SERVER_ERROR</H3>
+<PRE>
+public static final java.lang.String <B>ERROR_INTERNAL_SERVER_ERROR</B></PRE>
+<DL>
+<DD>A particular message could not be sent because the GCM servers encountered
+ an error. Used only on JSON requests, as in plain text requests internal
+ errors are indicated by a 500 response.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../../constant-values.html#com.google.android.gcm.server.Constants.ERROR_INTERNAL_SERVER_ERROR">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="ERROR_INVALID_TTL"><!-- --></A><H3>
+ERROR_INVALID_TTL</H3>
+<PRE>
+public static final java.lang.String <B>ERROR_INVALID_TTL</B></PRE>
+<DL>
+<DD>Time to Live value passed is less than zero or more than maximum.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../../constant-values.html#com.google.android.gcm.server.Constants.ERROR_INVALID_TTL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
 <A NAME="TOKEN_MESSAGE_ID"><!-- --></A><H3>
 TOKEN_MESSAGE_ID</H3>
 <PRE>
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/InvalidRequestException.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/InvalidRequestException.html
index 4b3271c..56de783 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/InvalidRequestException.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/InvalidRequestException.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:56 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 InvalidRequestException
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.Builder.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.Builder.html
index 5952e87..7d5110c 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.Builder.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.Builder.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Message.Builder
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.html
index 0773686..37a8a74 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Message.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Message
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/MulticastResult.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/MulticastResult.html
index f9df609..21752ca 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/MulticastResult.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/MulticastResult.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 MulticastResult
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Result.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Result.html
index 14d4b34..512b8f5 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Result.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Result.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Result
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Sender.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Sender.html
index 4f1a2ac..5224e15 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Sender.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/Sender.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Sender
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-frame.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-frame.html
index 8312f46..9f099b3 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-frame.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-frame.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 com.google.android.gcm.server
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 
 </HEAD>
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-summary.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-summary.html
index 27b0564..eddcca1 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-summary.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-summary.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 com.google.android.gcm.server
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-tree.html b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-tree.html
index 81efcef..d3d1c43 100644
--- a/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-tree.html
+++ b/docs/html/guide/google/gcm/server-javadoc/com/google/android/gcm/server/package-tree.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 com.google.android.gcm.server Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/constant-values.html b/docs/html/guide/google/gcm/server-javadoc/constant-values.html
index 5efe6f5..66df664 100644
--- a/docs/html/guide/google/gcm/server-javadoc/constant-values.html
+++ b/docs/html/guide/google/gcm/server-javadoc/constant-values.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Constant Field Values
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -107,12 +107,24 @@
 <TD ALIGN="right"><CODE>"DeviceQuotaExceeded"</CODE></TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="com.google.android.gcm.server.Constants.ERROR_INTERNAL_SERVER_ERROR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="com/google/android/gcm/server/Constants.html#ERROR_INTERNAL_SERVER_ERROR">ERROR_INTERNAL_SERVER_ERROR</A></CODE></TD>
+<TD ALIGN="right"><CODE>"InternalServerError"</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
 <A NAME="com.google.android.gcm.server.Constants.ERROR_INVALID_REGISTRATION"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
 <CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
 <TD ALIGN="left"><CODE><A HREF="com/google/android/gcm/server/Constants.html#ERROR_INVALID_REGISTRATION">ERROR_INVALID_REGISTRATION</A></CODE></TD>
 <TD ALIGN="right"><CODE>"InvalidRegistration"</CODE></TD>
 </TR>
 <TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="com.google.android.gcm.server.Constants.ERROR_INVALID_TTL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="com/google/android/gcm/server/Constants.html#ERROR_INVALID_TTL">ERROR_INVALID_TTL</A></CODE></TD>
+<TD ALIGN="right"><CODE>"InvalidTtl"</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
 <A NAME="com.google.android.gcm.server.Constants.ERROR_MESSAGE_TOO_BIG"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
 <CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
 <TD ALIGN="left"><CODE><A HREF="com/google/android/gcm/server/Constants.html#ERROR_MESSAGE_TOO_BIG">ERROR_MESSAGE_TOO_BIG</A></CODE></TD>
diff --git a/docs/html/guide/google/gcm/server-javadoc/default.css b/docs/html/guide/google/gcm/server-javadoc/default.css
new file mode 100644
index 0000000..2513e69
--- /dev/null
+++ b/docs/html/guide/google/gcm/server-javadoc/default.css
@@ -0,0 +1,4005 @@
+/* color definitions */
+/* 16 column layout */
+/* clearfix idiom */
+/* common mixins */
+/* page layout + top-level styles */
+::-webkit-selection,
+::-moz-selection,
+::selection {
+  background-color: #0099cc;
+  color: #fff; }
+
+html, body {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  background-color:#F9F9F9;
+  -webkit-font-smoothing: antialiased;
+  /* prevent subpixel antialiasing, which thickens the text */
+  /* text-rendering: optimizeLegibility; */
+  /* turned off ligatures due to bug 5945455 */ }
+
+body {
+  color: #222;
+  font: 14px/19px Roboto, sans-serif;
+  font-weight: 400;
+  letter-spacing:.1;
+  padding:0 10px; }
+
+#page-container {
+  width: 940px;
+  margin: 0 40px; }
+
+#page-header {
+  height: 80px;
+  margin-bottom: 20px;
+  font-size: 48px;
+  line-height: 48px;
+  font-weight: 100;
+  padding-left: 10px; }
+  #page-header a {
+    display: block;
+    position: relative;
+    top: 20px;
+    text-decoration: none;
+    color: #555555 !important; }
+
+#main-row {
+  display: inline-block; }
+  #main-row:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden; }
+  * html #main-row {
+    height: 1px; }
+
+#page-footer {
+  margin-left: 190px;
+  margin-top: 80px;
+  color: #999999;
+  padding-bottom: 40px;
+  font-size: 12px;
+  line-height: 15px; }
+  #page-footer a {
+    color: #777777; }
+  #page-footer #copyright {
+    margin-bottom: 10px; }
+
+#nav-container {
+  width: 160px;
+  min-height: 10px;
+  margin-right: 20px;
+  float: left; }
+
+#nav {
+  margin:0;
+  padding:0 0 30px;
+}
+
+#side-nav {
+  min-height:5px; /* silly way to avoid doc floating left when nav goes fixed */
+  margin-bottom:1px;
+}
+#devdoc-nav {
+  outline:none;
+  width:auto;
+  margin: 20px 0 0; }
+  
+#devdoc-nav h2 {
+  border:0;
+}
+
+#devdoc-nav.fixed {
+  position: fixed;
+  margin:0;
+  top: 20px; }
+
+#content {
+  width: 760px;
+  float: left; }
+
+a:hover,
+acronym:hover {
+  color: #7aa1b0 !important; }
+
+a:focus,
+a:active {
+  color: #33b5e5 !important; }
+
+img {
+  border: none; }
+#jd-content img {
+  margin-bottom:15px;
+}
+
+ul {
+  margin: 0;
+  padding: 0; }
+
+strong {
+  font-weight: 500; }
+
+em {
+  font-style: italic; }
+
+acronym {
+  border-bottom: 1px dotted #555555;
+  cursor: help; }
+
+acronym:hover {
+  border-bottom-color: #7aa1b0; }
+
+img.with-shadow,
+video.with-shadow {
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25); }
+
+/* disclosures mixin */
+/* content layout */
+.layout-content-row {
+  display: inline-block;
+  margin-bottom: 10px; }
+  .layout-content-row:after {
+    content: ".";
+    display: block;
+    height: 0;
+    clear: both;
+    visibility: hidden; }
+  * html .layout-content-row {
+    height: 1px; }
+
+.layout-content-col {
+  float: left;
+  margin-left: 20px; }
+  .layout-content-col:first-child {
+    margin-left: 0; }
+  .layout-content-col h3,
+  .layout-content-col h4 {
+    margin-top:0; }
+
+.layout-content-col.span-1 {
+  width: 40px; }
+
+.layout-content-col.span-2 {
+  width: 100px; }
+
+.layout-content-col.span-3 {
+  width: 160px; }
+
+.layout-content-col.span-4 {
+  width: 220px; }
+
+.layout-content-col.span-5 {
+  width: 280px; }
+
+.layout-content-col.span-6 {
+  width: 340px; }
+
+.layout-content-col.span-7 {
+  width: 400px; }
+
+.layout-content-col.span-8 {
+  width: 460px; }
+
+.layout-content-col.span-9 {
+  width: 520px; }
+
+.layout-content-col.span-10 {
+  width: 580px; }
+
+.layout-content-col.span-11 {
+  width: 640px; }
+
+.layout-content-col.span-12 {
+  width: 700px; }
+
+.layout-content-col.span-13 {
+  width: 760px; }
+
+.vspace.size-1 {
+  height: 10px; }
+
+.vspace.size-2 {
+  height: 20px; }
+
+.vspace.size-3 {
+  height: 30px; }
+
+.vspace.size-4 {
+  height: 40px; }
+
+.vspace.size-5 {
+  height: 50px; }
+
+.vspace.size-6 {
+  height: 60px; }
+
+.vspace.size-7 {
+  height: 70px; }
+
+.vspace.size-8 {
+  height: 80px; }
+
+.vspace.size-9 {
+  height: 90px; }
+
+.vspace.size-10 {
+  height: 100px; }
+
+.vspace.size-11 {
+  height: 110px; }
+
+.vspace.size-12 {
+  height: 120px; }
+
+.vspace.size-13 {
+  height: 130px; }
+
+.vspace.size-14 {
+  height: 140px; }
+
+.vspace.size-15 {
+  height: 150px; }
+
+.vspace.size-16 {
+  height: 160px; }
+
+/* nav */
+#nav {
+  /* section header divs */
+  /* expanded section header divs */
+  /* sublinks */ }
+  #nav li {
+    list-style-type: none;
+    font-size: 14px;
+    margin:0;
+    padding:0;
+    line-height: 15px; }
+  #nav a {
+    color: #555555;
+    text-decoration: none; }
+  #nav .nav-section-header {
+    position: relative;
+    margin-bottom: 1px;
+    padding: 0 30px 0 0; }
+  #nav li.selected a, #nav li.selected > .nav-section-header > a {
+    color: #09C;
+  }
+  #nav li.selected ul li a {
+  /* don't highlight child items */
+    color: #555555; }
+  #nav .nav-section .nav-section .nav-section-header {
+    /* no white line between second level sections */
+    margin-bottom: 0; }
+    /* section header links */
+    #nav > li > div > a {
+      display: block;
+      color: #333333;
+      font-weight: 500;
+      padding: 10px 0 10px 10px; }
+    #nav .nav-section-header:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_down.png) no-repeat scroll 50% 50%;
+      width: 34px;
+      height: 34px;
+      display: block;
+      position: absolute;
+      top: 0;
+      right: 0; }
+    #nav .nav-section-header.empty:after {
+      display: none; }
+    /* nested nav headers */
+    #nav .nav-section .nav-section {
+      position: relative;
+      padding: 0;
+      margin: 0; }
+    #nav .nav-section li a {
+    /* first gen child (2nd level li) */
+      display:block;
+      font-weight: normal;
+      text-transform: none;
+      padding: 7px 5px 7px 10px;
+       }
+    #nav .nav-section li li a {
+    /* second gen child (3rd level li) */
+      padding: 5px 5px 5px 10px;
+       }
+  #nav li.expanded .nav-section-header {
+    background:#e9e9e9;
+    background: rgba(0, 0, 0, 0.05); }
+  #nav li.expanded li .nav-section-header {
+    background: transparent; }
+  #nav li.expanded li ul {
+  /* 3rd level ul */
+    padding:0 10px;
+  }
+    #nav li.expanded > .nav-section-header:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_up.png) no-repeat scroll 50% 50%;
+      width: 34px;
+      height: 34px; }
+  #nav li ul {
+    display:none;
+    overflow: hidden;
+    margin: 0; }
+    #nav li ul.animate-height-in {
+      -webkit-transition: height 0.25s ease-in;
+      -moz-transition: height 0.25s ease-in;
+      transition: height 0.25s ease-in; }
+    #nav li ul.animate-height-out {
+      -webkit-transition: height 0.25s ease-out;
+      -moz-transition: height 0.25s ease-out;
+      transition: height 0.25s ease-out; }
+    #nav li ul li {
+      padding: 0; }
+      #nav li li li {
+        padding: 0; }
+  #nav li.expanded ul {
+    }
+    #nav li ul > li {
+      padding:0;
+    }
+    #nav li ul > li:last-child {
+      padding-bottom:5px;
+    }
+    #nav li.expanded ul > li {
+      background:#efefef;
+      background: rgba(0, 0, 0, 0.03); }
+    #nav li.expanded ul > li li {
+      background:inherit; }
+
+.new,
+.new-child {
+  font-size: .78em;
+  font-weight: bold;
+  color: #ff3d3d;
+  vertical-align:top;
+  white-space:nowrap;
+}
+
+/* content header */
+.content-header {
+  height: 30px;
+  margin:20px 0 25px;
+  padding:0 0 10px;}
+.content-header.just-links {
+  margin-bottom:0;
+  padding-bottom:0;}
+    
+.content-header h1 {
+  color:#000;
+  margin:0;
+  border-bottom:0;
+  padding:0;
+}
+
+.content-footer {
+  border-top: 1px solid #ccc;
+  margin-top: 10px;
+  padding-top:10px;
+  height: 30px; }
+
+.content-footer .col-9 {
+  margin-left:0;
+}
+.content-footer .col-4 {
+  margin-right:0;
+}
+.content-footer.wrap {
+  width:940px;
+}
+
+.paging-links {
+  position: relative; }
+  .paging-links a {
+    position: absolute; }
+  .paging-links a,
+  .training-nav-top a {
+    font-size: 14px;
+    line-height: 30px;
+    color: #555555;
+    text-decoration: none;
+    text-transform: uppercase; }
+  .paging-links .prev-page-link,
+  .training-nav-top .prev-page-link {
+    left: -5px; }
+    .paging-links .prev-page-link:before,
+    .training-nav-top .prev-page-link:before {
+      content: '';
+      background: transparent url(../images/styles/disclosure_left.png) no-repeat scroll 50% 50%;
+      width: 10px;
+      height: 10px;
+      display: inline-block;
+      margin-right: 5px; }
+  .paging-links .next-page-link,
+  .training-nav-top .next-page-link,
+    .training-nav-top .start-class-link,
+    .training-nav-top .start-course-link {
+    right: 10px; }
+    .next-page-link:after,
+    .start-class-link:after,
+    .start-course-link:after,
+    .next-class-link:after {
+      content: '';
+      background: transparent url(../images/styles/disclosure_right.png) no-repeat scroll 50% 50%;
+      width: 10px;
+      height: 10px;
+      display: inline-block;
+      margin-left: 5px; }
+      
+      
+  .training-nav-top a {
+    display:block;
+    float:left;
+    width:108px;
+    height:28px;
+    padding: 8px 15px;
+    line-height:28px;
+    text-align:center;
+    border:1px solid #DADADA;
+    border-bottom:0;
+  }
+      
+  .training-nav-top a.next-page-link {
+    border-left:0;
+    width:109px;
+  }
+      
+  .training-nav-top a.disabled,
+  .content-footer a.disabled {
+    color:#999;
+  }
+      
+  .training-nav-top a.disabled:hover,
+  .content-footer a.disabled:hover {
+    cursor:default;
+    color:#999 !important;
+  }
+      
+  .training-nav-top a.start-class-link,
+  .training-nav-top a.start-course-link {
+    width:248px;
+  }
+  
+  .hide {
+    display:none !important;
+  }
+  
+  .content-footer.next-class {
+    display:block;
+    border:0;
+    margin-top:0;
+    padding-top:0;
+  }
+  
+  .content-footer.next-class a.next-class-link {
+    display:block;
+    float:right;
+    text-transform:uppercase;
+  }
+
+/* content body */
+@-webkit-keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+@-moz-keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+@keyframes glowheader {
+  from {
+    background-color: #33b5e5;
+    color: #000;
+    border-bottom-color: #000; }
+
+  to {
+    background-color: transparent;
+    color: #33b5e5;
+    border-bottom-color: #33b5e5; } }
+
+h2:target,
+h3:target {
+    -webkit-animation-name: glowheader;
+    -moz-animation-name: glowheader;
+    animation-name: glowheader;
+    -webkit-animation-duration: 0.7s;
+    -moz-animation-duration: 0.7s;
+    animation-duration: 0.7s;
+    -webkit-animation-timing-function: ease-out;
+    -moz-animation-timing-function: ease-out;
+    animation-timing-function: ease-out; }
+
+.design ol h4 {
+  margin-bottom:0;
+}
+.design ol {
+  counter-reset: item; }
+  .design ol li {
+    font-size: 14px;
+    line-height: 20px;
+    list-style-type: none;
+    position: relative; }
+    .design ol li:before {
+      content: counter(item) ". ";
+      counter-increment: item;
+      position: absolute;
+      left: -20px;
+      top: 0; }
+    .design ol li.value-1:before {
+      content: "1. "; }
+    .design ol li.value-2:before {
+      content: "2. "; }
+    .design ol li.value-3:before {
+      content: "3. "; }
+    .design ol li.value-4:before {
+      content: "4. "; }
+    .design ol li.value-5:before {
+      content: "5. "; }
+    .design ol li.value-6:before {
+      content: "6. "; }
+    .design ol li.value-7:before {
+      content: "7. "; }
+    .design ol li.value-8:before {
+      content: "8. "; }
+    .design ol li.value-9:before {
+      content: "9. "; }
+    .design ol li.value-10:before {
+      content: "10. "; }
+.design .with-callouts ol li {
+  list-style-position: inside;
+  margin-left: 0; }
+  .design .with-callouts ol li:before {
+    display: inline;
+    left: -20px;
+    float: left;
+    width: 17px;
+    color: #33b5e5;
+    font-weight: 500; }
+
+/* special list items */
+li.no-bullet {
+  list-style-type: none !important; }
+li.no-bullet *{
+  margin:0; }
+
+.design li.with-icon {
+  position: relative;
+  margin-left: 20px;
+  min-height: 30px; }
+  .design li.with-icon p {
+    margin-left: 0 !important; }
+  .design li.with-icon:before {
+    position: absolute;
+    left: -40px;
+    top: 0;
+    content: '';
+    width: 30px;
+    height: 30px; }
+  .design li.with-icon.tablet:before {
+    background-image: url(../images/styles/ico_phone_tablet.png); }
+  .design li.with-icon.web:before {
+    background-image: url(../images/styles/ico_web.png); }
+  .design li.with-icon.action:before {
+    background-image: url(../images/styles/ico_action.png); }
+  .design li.with-icon.use:before {
+    background-image: url(../images/styles/ico_use.png); }
+
+/* figures and callouts */
+.figure {
+  position: relative; }
+  .figure.pad-below {
+    margin-bottom: 20px; }
+  .figure .figure-callout {
+    position: absolute;
+    color: #fff;
+    font-weight: 500;
+    font-size: 16px;
+    line-height: 23px;
+    text-align: center;
+    background: transparent url(../images/styles/callout.png) no-repeat scroll 50% 50%;
+    padding-right: 2px;
+    width: 30px;
+    height: 29px;
+    z-index: 1000; }
+    .figure .figure-callout.top {
+      top: -9px; }
+    .figure .figure-callout.right {
+      right: -5px; }
+
+.figure-caption {
+  margin: 0 10px 20px 0;
+  font-size: 14px;
+  line-height: 20px;
+  font-style: italic; }
+
+/* rows of figures */
+.figure-row {
+  font-size: 0;
+  line-height: 0;
+  /* to prevent space between figures */ }
+  .figure-row .figure {
+    display: inline-block;
+    vertical-align: top; }
+  .figure-row .figure + .figure {
+    margin-left: 10px;
+    /* reintroduce space between figures */ }
+
+/* video  containers */
+.framed-galaxynexus-land-span-13 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_land_span13.png) no-repeat
+scroll top left;
+  padding: 42px 122px 62px 126px;
+  overflow: hidden; }
+  .framed-galaxynexus-land-span-13, .framed-galaxynexus-land-span-13 video,
+.framed-galaxynexus-land-span-13 img {
+    width: 512px;
+    height: 286px; }
+
+.framed-galaxynexus-port-span-9 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_port_span9.png) no-repeat
+scroll top left;
+  padding: 95px 122px 107px 124px;
+  overflow: hidden; }
+  .framed-galaxynexus-port-span-9, .framed-galaxynexus-port-span-9 video,
+.framed-galaxynexus-port-span-9 img {
+    width: 274px;
+    height: 488px; }
+
+.framed-galaxynexus-port-span-5 {
+  background: transparent url(../images/styles/device_galaxynexus_blank_port_span5.png) no-repeat
+scroll top left;
+  padding: 75px 31px 76px 33px;
+  overflow: hidden; }
+  .framed-galaxynexus-port-span-5, .framed-galaxynexus-port-span-5 video,
+.framed-galaxynexus-port-span-5 img {
+    width: 216px;
+    height: 384px; }
+
+/* landing page disclosures */
+.landing-page-link {
+  text-decoration: none;
+  font-weight: 500;
+  color: #333333; }
+  .landing-page-link:after {
+    content: '';
+    background: transparent url(../images/styles/disclosure_right.png) no-repeat scroll 50% 50%;
+    width: 10px;
+    height: 10px;
+    display: inline-block;
+    margin-left: 5px; }
+
+/* tooltips */
+.tooltip-box {
+  position: absolute;
+  background-color: rgba(0, 0, 0, 0.9);
+  border-radius: 2px;
+  font-size: 14px;
+  line-height: 20px;
+  color: #fff;
+  padding: 6px 10px;
+  max-width: 250px;
+  z-index: 10000; }
+  .tooltip-box.below:after {
+    position: absolute;
+    content: '';
+    line-height: 0;
+    display: block;
+    top: -10px;
+    left: 5px;
+    border: 5px solid transparent;
+    border-bottom-color: rgba(0, 0, 0, 0.9); }
+
+/* video note */
+.video-instructions {
+  margin-top: 10px;
+  margin-bottom: 10px; }
+  .video-instructions:before {
+    content: '';
+    background: transparent url(../images/styles/ico_movie_inline.png) no-repeat scroll top left;
+    display: inline-block;
+    width: 12px;
+    height: 12px;
+    margin-right: 8px; }
+  .video-instructions:after {
+    content: 'Click device screen to replay movie.'; }
+
+/* download buttons */
+.download-button {
+  display: block;
+  margin-bottom: 5px;
+  text-decoration: none;
+  background-color: #33b5e5;
+  color: #fff !important;
+  font-weight: 500;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);
+  padding: 6px 12px;
+  border-radius: 2px; }
+  .download-button:hover, .download-button:focus {
+    background-color: #0099cc;
+    color: #fff !important; }
+  .download-button:active {
+    background-color: #006699; }
+
+/* UI tables and other things found in Writing style and Settings pattern */
+.ui-table {
+  width: 100%;
+  background-color: #282828;
+  color: #fff;
+  border-radius: 2px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
+  border-collapse: separate; }
+  .ui-table th,
+  .ui-table td {
+    padding: 5px 10px;
+    background-color: inherit; 
+    border:0;}
+  .ui-table thead th {
+    font-weight: bold; }
+  .ui-table tfoot td {
+    border-top: 1px solid #494949;
+    border-right: 1px solid #494949;
+    text-align: center; }
+    .ui-table tfoot td:last-child {
+      border-right: 0; }
+
+.layout-with-list-item-margins {
+  margin-left: 30px !important; }
+
+.emulate-content-left-padding {
+  margin-left: 10px; }
+
+.do-dont-label {
+  margin-bottom: 10px;
+  padding-left: 20px;
+  background: transparent none no-repeat scroll 0px 3px; }
+  .do-dont-label.bad {
+    background-image: url(../images/styles/ico_wrong.png); }
+  .do-dont-label.good {
+    background-image: url(../images/styles/ico_good.png); }
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***** PREVIOUSLY style.css ******************/
+
+
+
+
+
+@media screen, projection, print {
+[dir='rtl'] {
+    direction: rtl;
+}
+html {
+    line-height: 20px;
+}
+pre, table, input, textarea, code {
+    font-size: 1em;
+}
+address, abbr, cite {
+    font-style: normal;
+}
+[dir='rtl'] th {
+    text-align: right;
+}
+html[lang^=ja] blockquote, html[lang^=ja] q, html[lang^=ko] blockquote, html[lang^=ko] q,
+html[lang^=zh] blockquote, html[lang^=zh] q {
+    font-style: normal;
+}
+q {
+    font-style: italic;
+}
+fieldset, iframe, img {
+    border: 0;
+}
+img { 
+	-ms-interpolation-mode: bicubic;
+	vertical-align: middle;
+	max-width: 100%;
+}
+q {
+    quotes: none;
+}
+sup, sub {
+    font-size: 11px;
+    line-height: 0;
+}
+}
+
+@media screen, projection {
+
+table, fieldset {
+    margin: 0;
+}
+h1 {
+    color:#333;
+    font-size: 22px;
+    margin: 20px 0 20px;
+    padding:0 0 10px;
+}
+h1, h2 {
+    line-height: 32px;
+}
+h1.short {
+  margin-right:320px;
+}
+h1.short {
+  margin-right:320px;
+}
+h1.super {
+    font-size: 37px;	
+}
+h2 {
+    color:#333;
+    font-size: 20px;
+    margin: 20px 0 20px;
+    padding:0;
+}
+h3 {
+    color:#333;
+    font-size: 18px;
+}
+h3, h4 {
+    color:#333;
+    line-height: 20px;
+    margin: 10px 0;
+}
+h4 {
+	font-size: 16px;
+}
+h5 {
+	font-size: 14px;	
+}
+h5, h6 {
+	margin: 5px 0;
+}
+h6 {
+	font-size: 12px;	
+}
+hr { /* applied to the bottom of h2 elements */
+	height: 1px;
+	margin: 5px 0 20px;
+	border: 0;
+	background: #ccc;
+}
+p, pre, table, form {
+    margin: 0 0 15px;
+}
+small {
+	font-size: 11.5px;
+	color: #000;
+}
+ul, ol {
+    margin: 0 0 15px 18px;
+    padding: 0;
+}
+[dir='rtl'] ul, [dir='rtl'] ol {
+    margin: 10px 30px 10px 10px;
+}
+ul ul, ul ol, ol ul, ol ol {
+    margin-bottom: 0;
+    margin-top: 0;
+}
+li {
+  margin:0 0 4px;
+}
+dd {
+  margin:0 0 10px 30px;
+}
+dd p {
+  margin:10px 0 0;
+}
+ul p,
+ol p {
+  margin:10px 0 0;
+}
+pre strong, pre b, a strong, a b, a code {
+    color: inherit;
+}
+pre, code {
+    color: #060;
+    font: 14px/1.5 'courier new', courier, monospace;
+}
+code {
+    font-weight:bold;
+}
+
+legend {
+    display: none;
+}
+a:link, a:visited {
+  color: #258aaf;
+  text-decoration: none;
+}
+a:focus, a:hover, a:active {
+  color: #33B5E5;
+  text-decoration: none;
+}
+strong, b {
+  font-weight:bold;
+  color: #222;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+  border:0;
+  margin: .5em 1em 1em 0;
+  width:100%; /* consistent table widths; within IE's quirks */
+  background-color:#f7f7f7;
+}
+th, td {
+  padding: 4px 12px;
+  vertical-align: top;
+  text-align: left;
+}
+td {
+  background-color:inherit;
+  border:solid 1px #DDD;
+}
+th {
+  background-color: #999;
+  color: #fff;
+  border:solid 1px #DDD;
+  font-weight: normal;
+}
+tr:first-of-type th:first-of-type:empty {
+    visibility: hidden;
+}
+/* --------------------------------------------------------------------------
+Footer
+*/
+.line {
+    clear: both;
+    background: #acbc00;
+    background: -moz-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #acbc00),
+color-stop(50%, #acbc00), color-stop(50%, #bdde00), color-stop(100%, #bdde00));
+    background: -webkit-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -o-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: -ms-linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    background: linear-gradient(top, #acbc00 0, #acbc00 50%, #bdde00 50%, #bdde00 100%);
+    height: 2px;
+    margin-top: 150px;
+    position: relative;
+    z-index: 11;
+}
+#footer {
+    font-size:11px;
+    clear: both;
+    color: #999;
+    padding: 15px 0;
+    margin-top:10px;
+    width:auto;
+}
+#footer-local ul {
+	list-style: none;
+	margin: 5px 0 30px 0;
+}
+#footer-local li {
+    display: inline;
+}
+#footer-local li+li:before {
+    content: '|';
+    padding: 0 3px;
+	color: #e5e5e5;
+}
+#footer-global {
+    padding: 10px 15px;
+	background: #f5f5f5;
+}
+#footer-global {
+    border-top: 1px solid #ebebeb;
+    font-size: 11.5px;
+    line-height: 1.8;
+    list-style: none;
+}
+#footer-global ul {
+    margin: 0;
+}
+#footer-global li {
+    display: inline;
+    font-weight: bold;
+}
+#footer-global li+li:before {
+    content: '¬?';
+    padding: 0 3px;
+}
+* html #footer-global li {
+    margin: 0 13px 0 0;
+}
+* [dir='rtl'] #footer-global li {
+    margin: 0 0 0 13px;
+}
+*+html #footer-global li {
+    margin: 0 13px 0 0;
+}
+*+[dir='rtl'] #footer-global li {
+    margin: 0 0 0 13px;
+}
+#footer-global li a {
+    font-weight: normal;
+}
+.locales {
+  margin: 10px 0 0 0px;
+}
+[dir='rtl'] .locales {
+    background-position: right center;
+    float: left;
+    padding: 0 24px 0 0;
+}
+.locales form {
+    margin: 0;	
+}
+.locales select, .sites select {
+  line-height: 3.08;
+  margin: 0px 0;
+  border: solid 1px #EBEBEB;
+  -webkit-appearance: none;
+  background: white url('../images/arrows-up-down.png') right center no-repeat;
+  height: 30px;
+  color: #222;
+  line-height: normal;
+  padding: 5px;
+  width: 230px;
+}
+}
+
+/* =============================================================================
+   Print Only
+   ========================================================================== */
+@media print {
+a {
+    color: inherit;
+}
+.nav-x, .nav-y {
+    display: none;
+}
+.str { color: #060; }
+.kwd { color: #006; font-weight: bold; }
+.com { color: #600; font-style: italic; }
+.typ { color: #404; font-weight: bold; }
+.lit { color: #044; }
+.pun { color: #440; }
+.pln { color: #000; }
+.tag { color: #006; font-weight: bold; }
+.atn { color: #404; }
+.atv { color: #060; }
+}
+
+/* =============================================================================
+   Columns
+   ========================================================================== */
+
+@media screen, projection, print {
+.full {
+	padding: 2.5em 0;
+	border-top: solid 1px #ddd;
+	border-bottom: solid 1px #ddd;
+	background: #f7f7f7;	
+}
+.wrap {
+	margin: 0 auto;
+	width: 940px;
+	clear: both;
+}
+.cols {
+    height: 1%;
+    margin: 0 -1.533742331288343558282%;
+    width: 103.06748466257669%}
+*+html .cols {
+    margin-bottom: 20px;
+}
+.cols:after {
+    clear: both;
+    content: ' ';
+    display: block;
+    height: 0;
+    visibility: hidden;
+}
+.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12,
+.col-13, .col-14, .col-15, .col-16 {
+    display: inline;
+	float: left;
+	margin-left: 10px;
+	margin-right: 10px;
+}
+/*
+* html .col-1, * html .col-2, * html .col-3, * html .col-4, * html .col-5, * html .col-6, * html
+.col-7, * html .col-8, * html .col-9, * html .col-10, * html .col-11, * html .col-12  {
+    margin: 0;
+    padding: 0 1.4% 20px;
+}
+[dir='rtl'] .col-1, [dir='rtl'] .col-2, [dir='rtl'] .col-3, [dir='rtl'] .col-4, [dir='rtl'] .col-5,
+[dir='rtl'] .col-6, [dir='rtl'] .col-7, [dir='rtl'] .col-8, [dir='rtl'] .col-9, [dir='rtl'] .col-10,
+[dir='rtl'] .col-11, [dir='rtl'] .col-12 {
+    float: right;
+}
+*/
+.col-1 { width: 40px }
+.col-2 { width: 100px }
+.col-3 { width: 160px }
+.col-4 { width: 220px }
+.col-5 { width: 280px }
+.col-6 { width: 340px }
+.col-7 { width: 400px }
+.col-8 { width: 460px }
+.col-9 { width: 520px }
+.col-10 { width: 580px }
+.col-11 { width: 640px }
+.col-12 { width: 700px }
+.col-13 { width: 760px }
+.col-14 { width: 820px }
+.col-15 { width: 880px }
+.col-16 { width: 940px }
+}
+
+.col-right {
+  margin-right:0px;
+}
+
+@media screen and (max-width:772px) {
+.col-5, .col-6, .col-7 {
+    clear: both;
+    width: 97.0238096%}
+}
+
+/* =============================================================================
+   Layout
+   ========================================================================== */
+@media screen, projection, print {
+
+/* --------------------------------------------------------------------------
+Header, Login, Nav-X, Search
+*/
+#header {
+	padding: 2.2em 0 0.2em 0;
+}
+#header:before, #header:after {
+	content: "";
+	display: table;
+	clear: both
+}
+.logo, .nav-x {
+    float: left;
+}
+.nav-x {
+    margin-top: -2px;
+	list-style-type: none;
+}
+.nav-x a {
+    color: #333;
+    font-size: 16px;
+}
+.design a.selected {
+    color: #33b5e5;
+}
+.develop a.selected {
+    color: #F80;
+}
+.distribute a.selected {
+    color: #9C0;
+}
+
+
+
+.nav-x li {
+    display: inline;
+    margin-right: 45px;
+}
+.search {
+	float: right;
+	position: relative;
+	width: 220px
+}
+.search .bottom, .search .left, .search .right {
+	position: absolute;
+	background-color: #a3a3a3;
+}
+.search .bottom {
+	width: 220px;
+	height: 1px;
+	top: 24px;
+	left: 0
+}
+.search .left, .search .right {	
+	height: 5px;
+	width: 1px
+}
+.search .left {	top: 19px; left: 0 }
+.search .right { top: 19px; right: 0 }
+.search form {
+	float: left;
+	margin-top: 2px;
+	width: inherit;
+}
+.search .close,
+#player-frame .close {
+  position: absolute;
+  right: 8px;
+  bottom: 4px;
+  width: 16px;
+  height: 16px;
+  margin: 0;
+  text-indent: -1000em;
+  background: url(../images/close.png) no-repeat 0 0;
+  z-index:9999;
+}
+.search .close:hover, .search .close:focus,
+#player-frame .close:hover, #player-frame .close:focus {
+  background-position: -16px 0;
+  cursor:pointer;
+}
+#player-frame .close {
+  top: 6px;
+}
+.search form input {
+	color: #999;
+	font-size: 1em;
+	width: inherit;
+	border: none;
+	margin: 0;
+	padding:0 0 0 6px;
+	z-index: 1500;
+	background-color: transparent
+}
+.search:hover .bottom, .search:hover .left, .search:hover .right {
+	background-color: #33b5e5;
+}
+.search:hover .icon {
+	background-position: -8px 0
+}
+.search form input:focus {
+	color: #222;
+	font-weight: bold;
+	outline:0;
+}
+/* Search Dropdown */
+.search-dropdown {
+	padding: 15px;
+	width: 192px;
+	border: solid 1px #c5c5c5;
+	background: #fff;
+	position: absolute;
+	top: 35px;
+	left: 0;
+	-moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+	-webkit-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+	box-shadow: 0  0 10px rgba(0,0,0,0.2)
+}
+.search-dropdown ul, .search-dropdown ul li {
+	list-style-type: none;
+	margin: 0;
+	padding: 0
+}
+.search-dropdown ul li {
+	clear: both	
+}
+.search-dropdown img {
+	float: left;
+	margin: 0 10px 10px 0
+}
+.search-dropdown h6 {
+	color: #222;
+	margin: 0;
+	line-height: normal
+}
+.search-dropdown .desc {
+	color: #999;
+	font-size: 11.5px;
+	line-height: normal;
+	margin: 0;
+}
+.search-dropdown li a:hover h6, .search-dropdown li a:hover .desc {
+	color: #33b5e5
+}
+/* --------------------------------------------------------------------------
+Buttons
+*/
+.button, a.button, .button-secondary, a.button-secondary {
+	border-image: initial;
+    -webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+    cursor: pointer;
+}
+.button, a.button {
+    background-color: #09c;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2faddb), to(#09c));
+    background-image: -webkit-linear-gradient(top, #2faddb, #09c);
+    background-image: -moz-linear-gradient(top, #2faddb, #09c);
+    background-image: -ms-linear-gradient(top, #2faddb, #09c);
+    background-image: -o-linear-gradient(top, #2faddb, #09c);
+    background-image: linear-gradient(top, #2faddb, #09c);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#0099cc',GradientType=0);
+    border: 1px solid #3990ab;
+    color: #fff;
+}
+.button-secondary, a.button-secondary {
+    background-color: #f3f3f3;
+    border: 1px solid #dcdcdc;
+    color: #444;
+}
+a.button, a.button:visited, a.button-secondary, a.button-secondary:visited {
+    height: 28px;
+    line-height: 28px;
+    margin-right: 16px;
+	font-weight: 400;
+    min-width: 54px;
+    outline: 0;
+    padding: 8px 15px;
+    text-align: center;
+}
+.button, .button-secondary {
+    height: 34px;
+    line-height: 34px;
+    margin-right: 16px;
+	font-weight: 400;
+    min-width: 54px;
+    outline: 0;
+    padding: 0 15px;
+    text-align: center;
+}
+.button:hover, a.button:hover {
+    border-color: #09c;
+    background-color: #4cadcb;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#5dbcd9), to(#4cadcb));
+    background-image: -webkit-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -moz-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -ms-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: -o-linear-gradient(top, #5dbcd9, #4cadcb);
+    background-image: linear-gradient(top, #5dbcd9, #4cadcb);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5dbcd9',
+EndColorStr='#4cadcb',GradientType=0);
+    color: #fff !important;
+}
+.button:active, a.button:active {
+    background-color: #1e799a;
+    background-image: none;
+    border-color: #30b7e6;
+}
+.button-secondary:hover, a.button-secondary:hover {
+    border-color: #dbdbdb;
+    background-color: #f3f3f3;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
+    background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -moz-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -ms-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -o-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: linear-gradient(top, #f9f9f9, #ececec);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+    color: #33B5E5 !important;
+}
+.button-secondary:active, a.button-secondary:active {
+    border-color: #dadada;
+	background: #ebebeb; /* Old browsers */
+	/* IE9 SVG, needs conditional override of 'filter' to 'none' */
+	background:
+url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/
+Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0Jv
+eD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+
+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIg
+eDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ViZWJl
+YiIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjEwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2ZhZmFmYSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjkwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+
+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNmY2ZjYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFy
+R3JhZGllbnQ+
+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIg
+Lz4KPC9zdmc+);
+	background: -moz-linear-gradient(top,  #ebebeb 0%, #f9f9f9 5%, #fafafa 50%, #f9f9f9 90%,
+#ffffff 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ebebeb),
+color-stop(5%,#f9f9f9), color-stop(50%,#fafafa), color-stop(90%,#f9f9f9), color-stop(100%,#ffffff));
+/* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9
+90%,#ffffff 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* IE10+ */
+	background: linear-gradient(top,  #ebebeb 0%,#f9f9f9 5%,#fafafa 50%,#f9f9f9 90%,#ffffff
+100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ebebeb',
+endColorstr='#ffffff',GradientType=0 ); /* IE6-8 */
+	-webkit-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	-moz-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05); 
+	color: #258AAF !important;
+}
+.button.big {
+  font-size:20px;
+  display:inline-block;
+}
+
+.button.disabled,
+.button.disabled:hover,
+.button.disabled:active {
+  background:#ebebeb;
+  color:#999;
+  border-color:#999;
+  cursor:default;
+}
+
+.training-nav-top a.button-secondary,
+.training-nav-bottom a.button-secondary {
+  display:block;
+  float:left;
+  margin:0;
+  width:130px;
+  text-transform:uppercase;
+  font-weight:bold;
+  
+    background-color: #f3f3f3;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
+    background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -moz-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -ms-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: -o-linear-gradient(top, #f9f9f9, #ececec);
+    background-image: linear-gradient(top, #f9f9f9, #ececec);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+    color: #33B5E5;
+}
+
+.training-nav-top a.button-secondary:hover,
+.training-nav-bottom a.button-secondary:hover {
+    background-color: #09c;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2faddb), to(#09c));
+    background-image: -webkit-linear-gradient(top, #2faddb, #09c);
+    background-image: -moz-linear-gradient(top, #2faddb, #09c);
+    background-image: -ms-linear-gradient(top, #2faddb, #09c);
+    background-image: -o-linear-gradient(top, #2faddb, #09c);
+    background-image: linear-gradient(top, #2faddb, #09c);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#09c');
+    border: 1px solid #3990ab;
+    color: #fff !important;
+}
+
+.training-nav-top a.button-secondary.last,
+.training-nav-bottom a.button-secondary.last {
+  border-left:0;
+}
+
+.training-nav-top a.button-secondary.double-size,
+.training-nav-bottom a.button-secondary.double-size {
+  width:291px;
+}
+
+.training-nav-top,
+.training-nav-bottom {
+  float:right;
+  margin:0 0 0 20px;
+}
+
+.training-nav-bottom {
+  padding:0 0 20px;
+}
+
+#tb-wrapper,
+#qv-wrapper {
+  float:right;
+  clear:right;
+  margin:-27px 0 0 20px; /* negative top-margin to counter the content-header bottom margin */
+  padding:0 0 20px;
+}
+
+#tb,
+#qv {
+  font-size:13px;
+  line-height:18px;
+  width:238px;
+  border:1px solid #ccc;
+  float:right;
+}
+
+#tb {
+  width:278px;
+}
+
+#tb h2,
+#qv h2 {
+  margin:10px 15px;
+  padding:0;
+  text-transform:uppercase;
+  border-bottom:1px solid gainsboro;
+}
+
+#tb *,
+#qv * {
+  font-size:inherit;
+}
+
+#tb .download-box {
+  padding:0 0 0 15px;
+}
+
+#tb .download-box .filename {
+  font-size:11px;
+  margin:4px 4px 10px;
+  color:#666;
+}
+
+
+/* Dev guide quicknav */
+
+.sidebox-wrapper {
+  float:right;
+  clear:right;
+  margin:0 0 0 20px;
+  padding:0 0 20px;
+}
+
+.sidebox {
+  width:226px;
+  font-size:13px;
+  line-height:18px;
+  border-left:4px solid #99CC00;
+  float:right;
+  padding:0 0 0 10px;
+}
+
+.sidebox h2,
+.sidebox h3,
+.sidebox h4,
+.sidebox h5 {
+  font-weight:bold;
+  margin:0 0 10px;
+}
+
+.sidebox * {
+  font-size:inherit;
+}
+
+#tb ol,
+#tb ul,
+#qv ul {
+  margin:0 15px 10px 35px;
+}
+
+#qv ol {
+  list-style:none;
+  margin:0 15px 15px;
+  font-size:inherit;
+  line-height:inherit;
+}
+
+#tb ol ol,
+#tb ul ul,
+#qv ol ol,
+#qv ul ul,
+.sidebox ol ol,
+.sidebox ul ul {
+  margin-bottom:0;
+}
+
+#qv ol ol {
+  margin:3px 0 3px 15px;
+}
+
+.sidebox p,
+#qv p,
+#tb p {
+  margin: 0 0 10px;
+}
+
+
+/* --------------------------------------------------------------------------
+Form
+*/
+.article form {
+    margin: 0 0 20px;
+}
+.article form .form-required {
+    color: #dd4b39;
+}
+.article form fieldset {
+    margin: 0 0 20px;
+    padding: 0;
+}
+.article form legend {
+    display: block;
+    line-height: 1.5;
+    margin: 0;
+    padding: 0;
+}
+/*
+.article form ol, .article form ul {
+    margin: 0 0 0 1em;
+    padding: 0 0 0 1em;
+}
+[dir='rtl'] .article form ol, [dir='rtl'] .article form ul {
+    margin: 0 1em 0 0;
+    padding: 0 1em 0 0;
+}
+.article form ol ul, .article form ul ul, [dir='rtl'] .article form ol ul, [dir='rtl'] .article form
+ul ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+.article form li {
+    margin: 0 0 20px;
+}
+.article form li li {
+    margin: 0 0 5px;
+}
+*/
+.article form label {
+    display: block;
+    margin: 0 0 5px;
+    padding: 0;
+}
+.article form input[type='text'], .article form select, .article form textarea, .article form
+.checkbox-group, .article form .radio-group {
+    margin-bottom: 15px;
+}
+.checkbox-group input {
+	width: 13px;
+	height: 13px;
+	background: #fff;
+	border: solid 1px #c6c6c6;
+	float: left;
+}
+.article form .checkbox-group, .article form .radio-group {
+	display: block
+}
+.article form select {
+    border: solid 1px #ebebeb;
+    border-top-color: #ddd;
+    -webkit-appearance: none;
+    background: #f3f3f3 url(../images/arrows-up-down.png) right center no-repeat;
+    height: 30px;
+    color: #222;
+    line-height: normal;
+    padding: 5px;
+    width: 130px;
+}
+    
+.article form .browse .browse-msg {
+	font-size: 11.5px;	
+}
+.article form .browse .button-secondary {
+	height: auto;
+	line-height: 25px;
+	font-size: 11px;
+	padding: 0 8px;
+	margin: 0 10px 15px 0;
+}
+.article form input[type='text'], .article form textarea {
+    border: 1px solid #ebebeb;
+    border-top-color: #dcdcdc;
+    color: #222;
+    line-height: normal;
+    padding: 6px 10px;
+    width: 300px;	
+}
+.article form textarea {
+    height: 150px;
+}
+.article form input[type='text']:focus, .article form textarea:focus {
+    border-color: #33B5E5;
+    -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    -o-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2);
+    outline: 0;
+}
+.article form input[disabled], .article form textarea[disabled], .article form label.form-disabled {
+    color: #999;
+}
+.article form input[type='text'][disabled], .article form textarea[disabled] {
+    background-color: #ebebeb;
+}
+form .form-error input[type='text'], form .form-error textarea {
+    border-color: #dd4b39;
+	margin-right: 20px;
+}
+.aside {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+    margin: 10px 0;
+    padding: 20px;
+	color: #666;
+    position: relative;
+	background: #f9f9f9;
+}
+/*
+.aside, .notification, .promo {
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+    margin: 10px 0;
+    padding: 10px;
+    position: relative;
+}
+.aside>:first-child, .notification>:first-child, .promo>:first-child {
+    margin-top: 0;
+}
+.aside>:last-child, .notification>:last-child, .promo>:last-child {
+    margin-bottom: 0;
+}
+.aside {
+    background: #f9f9f9;
+}
+.notification {
+    background: #fffbe4;
+    border-color: #f8f6e6;
+}
+.promo {
+    background: #f6f9ff;
+    border-color: #eff2f9;
+}
+*/
+/* --------------------------------------------------------------------------
+Code Style
+*/
+pre {
+	margin: 1em 0;
+	padding: 1em;
+	overflow: auto;
+	border: solid 1px #ddd;
+	background: #f7f7f7;	
+}
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #828; }
+.atv { color: #080; }
+.dec { color: #606; }
+
+/* --------------------------------------------------------------------------
+Three-Pane
+*/
+/* Package Nav & Classes Nav */
+.three-pane {
+	position: relative;
+	border-top: solid 1px #ebebeb;
+}
+#packages-nav .js-pane,
+#classes-nav .js-pane {
+  overflow:visible;
+}
+#packages-nav {
+        height:270px;
+	max-height: inherit;
+	overflow: hidden;
+	position: relative;	
+}
+#classes-nav {
+	overflow: hidden;
+	position: relative;	
+}
+#packages-nav ul, #classes-nav ul {
+	list-style-type: none;
+	margin: 10px 0 20px 0;
+	padding: 0;	
+}
+#classes-nav li {
+	font-weight: bold;
+	margin: 5px 0;
+}
+#packages-nav li,
+#classes-nav li li {
+	margin: 0;
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li a, #classes-nav li a:active, #classes-nav li a:visited {
+	padding: 0 0 0 4px;
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li li a, #classes-nav li li a:active, #classes-nav li li a:visited,
+#nav-tree li a, #nav-tree li a:active, #nav-tree li a:visited {
+	color: #222;
+	font-weight: normal;	
+}
+#packages-nav li a, #packages-nav li a:active, #packages-nav li a:visited,
+#classes-nav li li a, #classes-nav li li a:active, #classes-nav li li a:visited {
+	display: block;
+}
+#packages-nav li.selected a, #packages-nav li.selected a:active, #packages-nav li.selected
+a:visited,
+#classes-nav li li.selected a, #classes-nav li li.selected a:active, #classes-nav li li.selected
+a:visited,
+#nav-tree li div.selected {
+    font-weight: 500;
+    color: #0099cc;
+    background-color:#fff; }
+  #packages-nav li.selected ul li a,
+  #classes-nav li.selected ul li a {
+  /* don't highlight child items */
+    color: #555555; }
+#nav-tree li div.selected a {
+    font-weight: 500;
+    color: #0099cc;
+}
+#nav-swap {
+  height:30px;
+  border-top:1px solid #ccc;
+}
+#nav-swap a {
+  display:inline-block;
+  height:100%;
+  color: #222;
+  font-size: 12px;
+  padding: 5px 0 5px 5px;
+}
+
+#nav-swap .fullscreen {
+  float: right;
+  width: 24px;
+  height: 24px;
+  text-indent: -1000em;
+  padding:0;
+  margin:3px 5px 0;
+  background: url(../images/fullscreen.png) no-repeat -24px 0;
+}
+#nav-swap .fullscreen.disabled {
+  background-position: 0 0;
+}
+#nav-swap .fullscreen:hover, 
+#nav-swap .fullscreen:focus {
+  cursor:pointer;
+}
+
+
+/* nav tree */
+#side-nav, #devdoc-nav, #swapper,
+#nav-tree, #tree-list {
+  overflow:hidden;
+  margin-left:0;
+}
+
+#nav-tree ul {
+  list-style:none;
+  padding:0;
+  margin:10px 0;
+}
+
+#nav-tree ul li div {
+  padding:0 0 0 4px;
+}
+
+#side-nav #nav-tree ul li a,
+#side-nav #nav-tree ul li span.no-children {
+  padding: 0;
+  margin: 0;
+}
+
+#nav-tree .plus {
+  margin: 0 3px 0 0;
+}
+
+#nav-tree ul ul {
+  list-style: none;
+  margin: 0;
+  padding: 0 0 0 0;
+}
+
+#nav-tree ul li {
+  margin: 0;
+  padding: 0 0 0 0;
+  white-space: nowrap;
+}
+
+#nav-tree .children_ul {
+  padding:0;
+  margin:0;
+}
+#nav-tree .children_ul li div {
+  padding:0 0 0 10px;
+}
+#nav-tree .children_ul .children_ul li div {
+  padding:0 0 0 20px;
+}
+
+#nav-tree a.nolink {
+  color: #222;
+  text-decoration: none;
+}
+
+#nav-tree span.label {
+  width: 100%;
+}
+
+#nav-tree {
+  overflow-x: auto;
+  overflow-y: scroll;
+  outline:0;
+}
+
+
+/* Content */
+#doc-col {
+  margin-right:0;
+}
+#doc-content-container {
+	margin-left: 291px	
+}
+#doc-header, #doc-content {
+	padding: 1em 2em;
+}
+#doc-header {
+	background: #f7f7f7;	
+}
+#doc-header h1 {
+	line-height: 0;
+	margin-bottom: 15px;
+}
+#api-info-block {
+	float: right;
+	font-weight: bold;
+}
+#api-info-block a, #api-info-block a:active, #api-info-block a:visited {
+	color: #222;
+}
+#api-info-block a:hover, #api-info-block a:focus {
+	color: #33B5E5;
+}
+#api-nav-header {
+  height:19px; /* plus 16px padding = 35; same as #nav li */
+  font-size:14px;
+  padding: 8px 0;
+  margin: 0;
+  border-bottom: 1px solid #CCC;
+  background:#e9e9e9;
+  background: rgba(0, 0, 0, 0.05); /* matches #nav li.expanded */
+
+}
+#api-nav-title {
+  padding:0 5px;
+  white-space:nowrap;
+}
+
+#api-level-toggle {
+  float:right;
+  padding:0 5px;
+}
+
+#api-level-toggle label {
+  margin:0;
+  vertical-align:top;
+  line-height: 19px;
+  font-size:13px;
+  height: 19px;
+}
+
+#api-level-toggle .select-wrapper {
+  width: 35px;
+  display: inline-block;
+  overflow: hidden;
+}
+#api-level-toggle select {
+  border: 0;
+  appearance:none;
+  -moz-appearance:none;
+  -webkit-appearance: none;
+  background: transparent url(../images/arrows-up-down.png) 23px 5px no-repeat;
+  color: #222;
+  height: 19px;
+  line-height: 19px;
+  padding: 0;
+  margin:1px 0 0 0;
+  width:150%;
+  font-size:13px;
+  vertical-align:top;
+  outline:0;
+}
+
+
+/* Toggle for revision notes and stuff */
+div.toggle-content.closed .toggle-content-toggleme {
+  display:none;
+}
+
+#jd-content img.toggle-content-img {
+  margin:0 5px 5px 0;
+}
+div.toggle-content > p {
+  padding:0 0 5px;
+}
+
+
+/* API LEVEL FILTERED MEMBERS */
+
+.absent,
+.absent a:link,
+.absent a:visited,
+.absent a:hover,
+.absent * {
+  color:#bbb !important;
+  cursor:default !important;
+  text-decoration:none !important;
+}
+#devdoc-nav li.absent.selected,
+#devdoc-nav li.absent.selected *,
+#devdoc-nav div.label.absent.selected,
+#devdoc-nav div.label.absent.selected * {
+  background-color:#eaeaea !important;
+}
+.absent h4.jd-details-title,
+.absent h4.jd-details-title * {
+  background-color:#f6f6f6 !important;
+}
+.absent img {
+  opacity: .3;
+  filter: alpha(opacity=30);
+  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
+}
+
+
+
+
+
+
+
+
+
+/* JQUERY RESIZABLE STYLES */
+.ui-resizable { position: relative; }
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; z-index:1; }
+.ui-resizable .ui-resizable-handle { display: block; border-bottom: 1px solid #e4e4e4; }
+/*body .ui-resizable-disabled .ui-resizable-handle { display: none; }
+body .ui-resizable-autohide .ui-resizable-handle { display: none; }*/
+.ui-resizable-s { cursor: s-resize; height: 10px; width: 100% !important; bottom: -11px; left: 0;
+border-bottom: solid 1px #ededed;
+  background: #f7f7f7 url("../images/resizable-s2.png") no-repeat scroll center center; }
+/*
+.ui-resizable-e { 
+cursor: e-resize; width: 10px; right: 0; top: 0; height: 100%; border-right: solid
+1px #ededed;background: #f7f7f7 url("../images/resizable-e2.png") no-repeat scroll center center; }
+*/
+
+/* --------------------------------------------------------------------------
+Lightbox
+*/
+.lightbox {	
+	width: 769px;
+	padding: 1.5em;
+	margin: 0 auto;
+	border: solid 1px #dcdcdc;
+	background: #fff;
+	-moz-box-shadow: 1px 1px 5px rgba(0,0,0,0.1);
+	-webkit-box-shadow: 1px 1px 5px rgba(0,0,0,0.1);
+	box-shadow: 1px 1px 5px rgba(0,0,0,0.1)
+}
+.lightbox .header {
+	float: left;
+	width: 720px;
+	margin: -10px 20px 10px 0;	
+}
+.lightbox .close {
+	float: right;
+	width: 10px;
+	height: 10px;
+	margin: -10px -10px 10px 0;
+	text-indent: -1000em;
+	background: url(../images/close.png) no-repeat 0 0;
+}
+.lightbox .close:hover, .lightbox .close:focus {
+	background-position: -10px 0;
+}
+
+/* --------------------------------------------------------------------------
+Misc
+*/
+
+
+.clearfix:before, .clearfix:after {
+	content: "";
+	display: table
+}
+.clearfix:after {
+	clear: both
+}
+.clearfix {
+	*zoom: 1
+}
+table.blank th, table.blank td {
+    border: 0;
+	background: none
+}
+.caption {
+	margin: 0.5em 0 2em 0;
+	color: #000;
+	font-size: 11.5px;	
+}
+
+.nolist {
+  list-style:none;
+  padding:0;
+  margin:0 0 1em 1em;
+}
+
+.nolist li {
+  padding:0 0 2px;
+  margin:0;
+}
+
+pre.classic {
+  background-color:transparent;
+  border:none;
+  padding:0;
+}
+
+p.img-caption {
+  margin: -10px 0 20px;
+  font-size:13px;
+  color:#666;
+}
+
+div.figure {
+  float:right;
+  clear:right;
+  margin:10px 0 0 0;
+  padding:0 0 0 20px;
+  /* width must be defined w/ an inline style matching the image width */
+}
+
+p.table-caption {
+  margin: 0 0 4px 0; /* matches default table left-margin */
+  font-size:13px;
+  color:#666;
+}
+
+p.note, div.note, 
+p.caution, div.caution, 
+p.warning, div.warning {
+  padding: 0 0 0 10px;
+  border-left: 4px solid;
+}
+
+p.note {
+  border-color: #258AAF;
+}
+
+p.caution {
+  border-color: #FF8800;
+}
+
+p.warning {
+  border-color: #ff4443;
+}
+
+div.note.design {
+  border-left: 4px solid #33B5E5;
+}
+
+div.note.develop {
+  border-left: 4px solid #F80;
+}
+
+div.note.distribute {
+  border-left: 4px solid #9C0;
+}
+
+.note p, .caution p, .warning p {
+  margin:0 0 5px;
+}
+
+.note p:last-child, .caution p:last-child, .warning p:last-child {
+  margin-bottom:0;
+}
+
+blockquote {
+  display:block;
+  float:right;
+  width:280px;
+  font-size:20px;
+  font-style:italic;
+  line-height:24px;
+  color:#33B5E5;
+  margin:0 0 20px 30px;
+}
+
+div.design-announce p {
+  margin:0 0 10px;
+}
+
+#devdoc-nav a.totop {
+  display:block;
+  top:0;
+  width:inherit;
+  background: transparent url(../images/styles/gototop.png) no-repeat scroll 50% 50%;
+  text-indent:-9999em;
+}
+#devdoc-nav a.totop {
+  position:fixed;
+  display:none;
+}
+#devdoc-nav a.totop:hover {
+  background-color:#33B5E5;
+}
+
+.content-footer a.totop {
+  text-transform:uppercase;
+  line-height:30px;
+}
+
+/* -----------------------------------------------
+Dialog box for popup messages 
+*/
+
+div.dialog {
+  height:0;
+  margin:0 auto;
+}
+
+div.dialog>div {
+  z-index:99;
+  position:fixed;
+  margin:70px 0;
+  width: 391px;
+  height: 200px;
+  background: #F7F7F7;
+-moz-box-shadow: 0 0 15px rgba(0,0,0,0.5);
+-webkit-box-shadow: 0 0 15px rgba(0,0,0,0.5);
+box-shadow: 0 0 15px rgba(0,0,0,0.5);
+}
+/* IE6 can't position fixed */
+* html div.dialog div { position:absolute; }
+
+
+div#deprecatedSticker {
+  display:none;
+  z-index:99;
+  position:fixed;
+  right:15px;
+  top:114px;
+  margin:0;
+  padding:1em;
+  background:#FFF;
+  border:1px solid #dddd00;
+  box-shadow:-5px 5px 10px #ccc;
+  -moz-box-shadow:-5px 5px 10px #ccc;
+  -webkit-box-shadow:-5px 5px 10px #ccc;
+}
+
+div#naMessage {
+  display:none;
+  width:555px;
+  height:0;
+  margin:0 auto;
+}
+
+div#naMessage div {
+  z-index:99;
+  width:450px;
+  position:fixed;
+  margin:50px 0;
+  padding:4em 4em 3em;
+  background:#FFF;
+  border:1px solid #999;
+  box-shadow:-10px 10px 40px #888;
+  -moz-box-shadow:-10px 10px 40px #888;
+  -webkit-box-shadow:-10px 10px 40px #888;
+}
+/* IE6 can't position fixed */
+* html div#naMessage div { position:absolute; }
+
+div#naMessage strong {
+  font-size:1.1em;
+}
+
+
+/* --------------------------------------------------------------------------
+Slideshow Controls & Next/Prev 
+*/
+.slideshow-next, .slideshow-prev {	
+	width: 20px;
+	height: 36px;
+	text-indent: -1000em;
+}
+.slideshow-container {
+	margin: 2em 0;
+}
+.slideshow-container:before, .slideshow-container:after {
+	content: "";
+	display: table;
+	clear: both;
+}
+a.slideshow-next, a.slideshow-next:visited {
+
+	float: right;
+
+	background: url(../images/arrow-right.png) no-repeat 0 0
+
+}
+
+a.slideshow-prev, a.slideshow-prev:visited {
+
+	float: left;	
+
+	background: url(../images/arrow-left.png) no-repeat 0 0
+
+}
+
+.slideshow-next:hover, .slideshow-prev:hover, .slideshow-next:focus, .slideshow-prev:focus {
+
+	background-position: 0 -36px	
+
+}
+
+.slideshow-next:active, .slideshow-prev:active {
+
+	background-position: 0 -72px	
+
+}
+.slideshow-nav {
+	width: 74px;
+	margin: 0 auto;		
+}
+.slideshow-nav a, .slideshow-nav a:visited {
+	display: inline-block;
+	width: 12px;
+	height: 12px;
+	margin: 0 2px 20px 2px;
+	background: #ccc;
+	-webkit-border-radius: 50%;
+	-moz-border-radius: 50%;
+	border-radius: 50%;
+}
+.slideshow-nav a:hover, .slideshow-nav a:focus {
+
+	background: #33B5E5
+}
+
+.slideshow-nav a:active {
+
+	background: #1e799a;
+	background: #ebebeb;	
+	-webkit-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	-moz-box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+	box-shadow: inset 0px 0px 5px 2px rgba(0, 0, 0, .05);
+}
+.slideshow-nav a.active, .slideshow-nav a.active:active, .slideshow-nav a.active:visited {
+	background: #33B5E5
+}
+/* --------------------------------------------------------------------------
+Tabs
+*/
+ul.tabs {
+	padding: 0;
+	margin: 2em 0 0 0;	
+}
+ul.tabs:before, ul.tabs:after {
+	content: "";
+	display: table;
+	clear: both;
+}
+ul.tabs li {
+	list-style-type: none;
+	float: left;	
+}
+ul.tabs li a, ul.tabs li a:active, ul.tabs li a:visited {
+	display: block;
+	height: 36px;
+	line-height: 36px;
+	padding: 0 15px;
+	margin-right: 2px;
+	color: #222;
+	-moz-border-radius-topleft: 2px;
+	-moz-border-radius-topright: 2px;
+	-moz-border-radius-bottomright: px;
+	-moz-border-radius-bottomleft: px;
+	-webkit-border-radius: 2px 2px px px;
+	border-radius: 2px 2px px px; 
+	border-top: solid 1px #ebebeb;
+	border-left: solid 1px #ebebeb;
+	border-right: solid 1px #ebebeb;
+	background-color: #fff;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#fafafa));
+    background-image: -webkit-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -moz-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -ms-linear-gradient(top, #ffffff, #fafafa);
+    background-image: -o-linear-gradient(top, #ffffff, #fafafa);
+    background-image: linear-gradient(top, #ffffff, #fafafa);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff',
+EndColorStr='#fafafa');
+}
+ul.tabs li a:hover {
+	color: #33B5E5;	
+}
+ul.tabs li a.selected {
+	height: 37px;
+	color: #33B5E5;
+	background-color: #f7f7f7;
+	background-image: none;
+	border-color: #ddd;
+}
+.tab-content {
+	padding: 1.2em;
+	margin: -1px 0 2em 0;
+	-webkit-border-radius: 2px;
+    -moz-border-radius: 2px;
+    border-radius: 2px;
+	border: solid 1px #ddd;
+	background: #f7f7f7;
+}
+/* --------------------------------------------------------------------------
+Feature Boxes
+*/
+.feature-box {
+  width: 291px;
+  height: 200px;
+  position: relative;
+  background: #F7F7F7;
+}
+.box-border .top, .box-border .bottom, .box-border .left, .box-border .right {
+	z-index: 100;
+	position: absolute;
+	background-color: #aaa;
+}
+.box-border .top, .box-border .bottom {
+	width: 291px;
+	height: 1px;
+}
+.dialog .box-border .top,
+.dialog .box-border .bottom { width:391px; }
+
+.box-border .left, .box-border .right {	
+	width: 1px;
+	height: 8px;		
+}
+.box-border .top { top: 0; left: 0 }
+.box-border .top .left { top: 1px; left: 0 }
+.box-border .top .right { top: 1px; right: 0 }
+.box-border .bottom .left { top: -8px; left: 0 }
+.box-border .bottom { top: 200px; left: 0 }
+.box-border .bottom .right { top: -8px; right: 0 }
+
+.feature-box h4,
+.dialog h4 {
+    margin: 15px 18px 10px;
+    padding:0;
+}
+
+.feature-box p,
+.dialog p {
+    margin: 10px 18px;
+    padding:0;
+}
+.feature-box .link,
+.dialog .link {
+    border-top: 1px solid #dedede;
+    bottom: 0;
+    position: absolute;
+    width: inherit;
+}
+.feature-box a, .feature-box h4,
+.dialog a, .dialog h4 {
+    -webkit-transition: color .4s ease;
+    -moz-transition: color .4s ease;
+    -o-transition: color .4s ease;
+    transition: color .4s ease;
+}
+.feature-box:hover {
+	cursor: pointer;	
+}
+.feature-box:hover .box-border .top, .feature-box:hover .box-border .bottom, .feature-box:hover
+.left, .feature-box:hover .right {	
+	background-color: #33B5E5;
+}
+.feature-box:hover h4, .feature-box:hover a {
+	color: #33B5E5;
+}
+/* --------------------------------------------------------------------------
+Page-Specific Styles
+*/
+.colors { 
+	position: relative;
+	float: left;
+	width: 92px;
+	margin: 40px 0 20px;
+}
+.colors div {
+	color: #fff;
+	font-size: 11.5px;
+	width: 82px;
+	height: 82px;
+	margin-top:-30px;
+	line-height: 82px;
+	text-align: center;
+	border: solid 5px #fff;
+	-webkit-border-radius: 50%;
+	-moz-border-radius: 50%;
+	border-radius: 50%;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ########### REFERENCE DOCS ################## */
+
+#packages-nav h2,
+#classes-nav h2 {
+  font-size:18px;
+  margin:0;
+  padding:0 0 0 4px;
+}
+
+#jd-header {
+  padding: 0 0 5px;
+  margin: 20px 0 10px;
+  font-size:13px;
+  border-bottom:solid 1px #ccc;
+}
+
+#jd-header h1 {
+  margin:0;
+  padding:0;
+}
+
+/* page-top-right container for reference pages (holds
+links to summary tables) */
+#api-info-block {
+  font-size:13px;
+  margin:20px 0 0;
+  padding:0 10px 6px;
+  font-weight:normal;
+  float:right;
+  text-align:right;
+  color:#999;
+  max-width:70%;
+}
+
+#api-info-block div.api-level {
+  font-weight:bold;
+  font-size:inherit;
+  float:none;
+  color:#222;
+  padding:0;
+  margin:0;
+}
+
+/* inheritance table */
+.jd-inheritance-table {
+  border-spacing:0;
+  margin:0;
+  padding:0;
+  font-size:13px;
+  background-color:transparent;
+}
+.jd-inheritance-table tr td {
+  border: none;
+  margin: 0;
+  padding: 0;
+  background-color:transparent;
+}
+.jd-inheritance-table .jd-inheritance-space {
+  font-weight:bold;
+  width:1em;
+}
+.jd-inheritance-table .jd-inheritance-interface-cell {
+  padding-left: 17px;
+}
+
+
+
+.jd-sumtable a {
+  text-decoration:none;
+}
+
+.jd-sumtable a:hover {
+  text-decoration:underline;
+}
+
+/* the link inside a sumtable for "Show All/Hide All" */
+.toggle-all {
+  display:block;
+  float:right;
+  font-weight:normal;
+  font-size:0.9em;
+}
+
+/* adjustments for in/direct subclasses tables */
+.jd-sumtable.jd-sumtable-subclasses {
+  margin: 1em 0 0 0;
+  max-width:968px;
+  background-color:transparent;
+  font-size:13px;
+}
+
+/* extra space between end of method name and open-paren */
+.sympad {
+  margin-right: 2px;
+}
+
+/* right alignment for the return type in sumtable */
+.jd-sumtable .jd-typecol {
+  text-align:right;
+}
+
+/* adjustments for the expando table-in-table */
+.jd-sumtable-expando {
+  margin:.5em 0;
+  padding:0;
+}
+
+/* a div that holds a short description */
+.jd-descrdiv {
+  padding:3px 1em 0 1em;
+  margin:0;
+  border:0;
+}
+
+#jd-content img.jd-expando-trigger-img {
+  padding:0 4px 4px 0;
+  margin:0;
+}
+
+.jd-sumtable-subclasses div#subclasses-direct,
+.jd-sumtable-subclasses div#subclasses-indirect {
+  margin:0 0 0 13px;
+}
+
+
+
+/********* MEMBER REF *************/
+
+
+.jd-details {
+/*  border:1px solid #669999;
+  padding:4px; */
+  margin:0 0 1em;
+}
+
+/* API reference: a container for the
+.tagdata blocks that make up the detailed
+description */
+.jd-details-descr {
+  padding:0;
+  margin:.5em .25em;
+}
+
+/* API reference: a block containing
+a detailed description, a params table,
+seealso list, etc */
+.jd-tagdata {
+  margin:.5em 1em;
+}
+
+.jd-tagdata p {
+  margin:0 0 1em 1em;
+}
+
+/* API reference: adjustments to
+the detailed description block */
+.jd-tagdescr {
+  margin:.25em 0 .75em 0;
+}
+
+.jd-tagdescr ol,
+.jd-tagdescr ul {
+  margin:0 2.5em;
+  padding:0;
+}
+
+.jd-tagdescr table,
+.jd-tagdescr img {
+  margin:.25em 1em;
+}
+
+.jd-tagdescr li {
+margin:0 0 .25em 0;
+padding:0;
+}
+
+/* API reference: heading marking
+the details section for constants,
+attrs, methods, etc. */
+h4.jd-details-title {
+  font-size:1.15em;
+  background-color: #E2E2E2;
+  margin:1.5em 0 .6em;
+  padding:3px 95px 3px 3px; /* room for api-level */
+}
+
+h4.jd-tagtitle {
+  margin:0;
+}
+
+h4 .normal {
+  font-weight:normal;
+}
+
+/* API reference: heading for "Parameters", "See Also", etc.,
+in details sections */
+h5.jd-tagtitle {
+  margin:0 0 .25em 0;
+  font-size:1em;
+}
+
+.jd-tagtable {
+  margin:0;
+  background-color:transparent;
+  width:auto;
+}
+
+.jd-tagtable td,
+.jd-tagtable th {
+  border:none;
+  background-color:#fff;
+  vertical-align:top;
+  font-weight:normal;
+  padding:2px 10px;
+}
+
+.jd-tagtable th {
+  font-style:italic;
+}
+
+/* Inline api level indicator for methods */
+div.api-level {
+  font-size:.8em;
+  font-weight:normal;
+  color:#999;
+  float:right;
+  padding:0 8px 0;
+  margin-top:-30px;
+}
+
+table.jd-tagtable td,
+table.jd-tagtable th {
+  background-color:transparent;
+}
+
+table.jd-tagtable th {
+  color:inherit;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* SEARCH FILTER */
+
+#search_autocomplete {
+  font-weight:normal;
+}
+
+#search_filtered_wrapper {
+  width: 193px;
+  float: right;
+}
+#search_filtered_div {
+  position:absolute;
+  z-index:9999;
+  min-width:171px; /* +padding and border makes this match input width */
+  padding:5px;
+  border: solid 1px #C5C5C5;
+  background: white;
+  top: 35px;
+  -moz-box-shadow: 0 0 10px rgba(0,0,0,0.2);
+  -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
+}
+
+ul#search_filtered {
+  min-width:100%;
+  margin:0;
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+
+#search_filtered li{
+  line-height:1.5em;
+  margin: 0 0 2px;
+  padding: 0;
+}
+
+#search_filtered li a {
+  padding:0 5px;
+  color:#222 !important;
+}
+
+#search_filtered .jd-selected {
+  background-color: #33B5E5;
+  cursor:pointer;
+}
+#search_filtered .jd-selected,
+#search_filtered .jd-selected a {
+  color:#f7f7f7 !important;
+}
+
+.no-display {
+  display: none;
+}
+
+.jd-autocomplete {
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  font-size: 0.81em;
+  border: none;
+  margin: 0;
+  line-height: 1.05em;
+}
+
+.show-item {
+  display: table-row;
+}
+.hide-item {
+  display: hidden;
+}
+
+
+
+
+
+/* SEARCH RESULTS */
+
+/* disable twiddle and size selectors for left column */
+#leftSearchControl div {
+  padding:0;
+}
+
+#leftSearchControl .gsc-twiddle {
+  background-image : none;
+}
+
+#leftSearchControl td, #searchForm td {
+  border: 0px solid #000;
+  padding:0;
+}
+
+#leftSearchControl .gsc-resultsHeader .gsc-title {
+  padding-left : 0px;
+  font-weight : bold;
+  font-size : 13px;
+  color:#006699;
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsHeader div.gsc-results-selector {
+  display : none;
+}
+
+#leftSearchControl .gsc-resultsRoot {
+  padding-top : 6px;
+}
+
+#leftSearchControl div.gs-visibleUrl-long {
+  display : block;
+  color:#006699;
+}
+
+#leftSearchControl .gsc-webResult {
+  padding:0 0 20px 0;
+}
+
+.gsc-webResult div.gs-visibleUrl-short,
+table.gsc-branding,
+.gsc-clear-button {
+  display : none;
+}
+
+.gsc-cursor-box .gsc-cursor div.gsc-cursor-page,
+.gsc-cursor-box .gsc-trailing-more-results a.gsc-trailing-more-results,
+#leftSearchControl a,
+#leftSearchControl a b {
+  color:#006699;
+}
+
+.gsc-resultsHeader {
+  display: none;
+}
+
+/* Disable built in search forms */
+.gsc-control form.gsc-search-box {
+  display : none;
+}
+table.gsc-search-box {
+  margin:6px 0 0 0;
+  border-collapse:collapse;
+}
+
+td.gsc-input {
+  padding:0 2px;
+  width:100%;
+  vertical-align:middle;
+}
+
+input.gsc-input {
+  border:1px solid #BCCDF0;
+  width:99%;
+  padding-left:2px;
+  font-size:.95em;
+}
+
+td.gsc-search-button {
+  text-align: right;
+  padding:0;
+  vertical-align:top;
+}
+
+
+#searchResults {
+  overflow:hidden; /* because the repositioned page links makes the section think it needs to scroll
+(it doesn't) */
+  height:auto;
+}
+
+#searchResults .gsc-control {
+  position:relative;
+  width:auto;
+  padding:0 0 10px;
+}
+
+#searchResults .gsc-tabsArea {
+  position:relative;
+  white-space:nowrap;
+  float:left;
+  width:200px;
+}
+
+#searchResults .gsc-above-wrapper-area {
+  display:none;
+}
+
+#searchResults .gsc-resultsbox-visible {
+  float:left;
+  width:720px;
+  margin-left:20px;
+}
+
+#searchResults .gsc-tabHeader {
+  padding: 3px 6px;
+  position:relative;
+  width:auto;
+  display:block;
+}
+
+#searchResults h2#searchTitle {
+  padding:0;
+  margin:5px 0;
+  border:none;
+}
+
+#searchResults h2#searchTitle em {
+  font-style:normal;
+  color:#33B5E5;
+}
+
+#searchResults .gsc-table-result {
+  margin:5px 0 10px 0;
+  background-color:transparent;
+}
+#searchResults .gs-web-image-box, .gs-promotion-image-box {
+  width:120px;
+}
+#searchResults .gs-web-image-box img.gs-image, .gs-promotion-image-box img.gs-promotion-image {
+  max-width:120px;
+}
+
+#searchResults .gsc-table-result .gsc-thumbnail {
+  padding:0 20px 0 0;
+}
+
+#searchResults td {
+  background-color:transparent;
+}
+
+#searchResults .gsc-expansionArea {
+  position:relative;
+}
+#searchResults .gsc-tabsArea .gsc-cursor-box {
+  width:200px;
+  padding:20px 0 0 1px;
+}
+#searchResults .gsc-cursor-page {
+  display:inline-block;
+  float:left;
+  margin:-1px 0 0 -1px;
+  padding:0;
+  height:27px;
+  width:27px;
+  text-align:center;
+  line-height:2;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhInactive,
+#searchResults .gsc-cursor-page {
+  text-decoration:none;
+  color:#258AAF;
+  border: solid 1px #DADADA;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhInactive:hover,
+#searchResults .gsc-cursor-page:hover {
+  border-color: #DBDBDB;
+  background-color: #F3F3F3;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#F9F9F9), to(#ECECEC));
+  background-image: -webkit-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -moz-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -ms-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: -o-linear-gradient(top, #F9F9F9, #ECECEC);
+  background-image: linear-gradient(top, #F9F9F9, #ECECEC);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f9f9f9',
+EndColorStr='#ececec');
+  color: #33B5E5;
+}
+
+#searchResults .gsc-tabHeader.gsc-tabhActive,
+#searchResults .gsc-tabHeader.gsc-tabhActive:hover,
+#searchResults .gsc-cursor-page.gsc-cursor-current-page,
+#searchResults .gsc-cursor-page.gsc-cursor-current-page:hover {
+  color:#fff;
+  background-color: #09C;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2FADDB), to(#09C));
+  background-image: -webkit-linear-gradient(top, #2FADDB, #09C);
+  background-image: -moz-linear-gradient(top, #2FADDB, #09C);
+  background-image: -ms-linear-gradient(top, #2FADDB, #09C);
+  background-image: -o-linear-gradient(top, #2FADDB, #09C);
+  background-image: linear-gradient(top, #2FADDB, #09C);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#2faddb', EndColorStr='#09c');
+  border: 1px solid #3990AB;
+  z-index:100;
+}
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*********** PREVIOUSLY dac-styles.css ***************/
+
+
+
+
+
+::-webkit-selection,
+::-moz-selection,
+::selection {
+  background-color: #0099cc;
+  color: #fff; }
+
+#header {
+  border-bottom:0;
+}
+
+#header .wrap {
+  max-width:940px;
+  height:41px;
+  border-bottom:1px solid;
+  border-color: #ccc;
+  position:relative;
+}
+
+.about #header .wrap {
+  border-color: #9933CC;
+}
+
+.design #header .wrap {
+  border-color: #33b5e5;
+}
+
+.develop #header .wrap {
+  border-color: #F80;
+}
+
+.distribute #header .wrap {
+  border-color: #9C0;
+}
+
+.logo a {
+  width:123px;
+  float:left;
+}
+
+#header .logo {
+  margin-top: -6px;
+  margin-left: 0px;
+  margin-bottom:0px;
+  width: 160px;
+  padding-right:10px;
+}
+
+.search {
+  height:25px;
+  margin-top: -3px;
+  margin-bottom: 0px;
+}
+
+
+
+/* Quicknav */
+.btn-quicknav {
+  width:20px;
+  height:28px;
+  float:left;
+  margin-left:6px;
+  padding-right:10px;
+  position:relative;
+  cursor:pointer;
+  border-right:1px solid #CCC;
+}
+
+.btn-quicknav a {
+  zoom:1;
+  position:absolute;
+  top:13px;
+  left:5px;
+  display:block;
+  text-indent:-9999em;
+  width:10px;
+  height:5px;
+  background:url(../images/quicknav_arrow.png) no-repeat;
+}
+
+.btn-quicknav a.arrow-active {
+  background-position: 0 -5px;
+  display:none;
+}
+
+#header-wrap.quicknav a.arrow-inactive {
+  display:none;
+}
+
+.btn-quicknav.active a.arrow-active {
+  display:block;
+}
+
+.nav-x li {
+  display:block;
+  float:left;
+  margin-right:45px;
+  -webkit-transition: all 0.25s linear;
+      -moz-transition: all 0.25s linear;
+       -ms-transition: all 0.25s linear;
+        -o-transition: all 0.25s linear;
+           transition: all 0.25s linear;
+}
+
+#header-wrap.quicknav .nav-x li {
+  min-width:160px;
+  margin-right:20px;
+}
+
+#header-wrap.quicknav li.last {
+  margin-right:0px;
+}
+
+#quicknav {
+ float:none; 
+ clear:both;
+ margin-left:180px;
+ margin-top:-30px;
+ display:none;
+ overflow:hidden;
+}
+
+#header-wrap.quicknav #quicknav {
+
+}
+
+#quicknav ul {
+  margin:10px 0;
+  padding:0;
+}
+
+#quicknav ul li.design {
+  border-top:1px solid #33b5e5;
+}
+
+#quicknav ul li.develop {
+  border-top:1px solid #FF8800;
+}
+
+#quicknav ul li.distribute {
+  border-top:1px solid #99cc00;
+}
+
+#quicknav ul li {
+  display:block;
+  float:left;
+  margin:0 20px 0 0;
+  min-width:140px;
+}
+
+#quicknav ul li.last {
+  margin-right:0px;
+}
+
+#quicknav ul li ul li {
+  float:none;
+}
+
+#quicknav ul li ul li a {
+  color:#222;
+}
+
+#quicknav ul li li ul,
+#quicknav ul li li ul li {
+  margin:0;
+}
+
+#quicknav ul li li ul li:before {
+  content:"\21B3";
+}
+
+#header-wrap {
+   -webkit-transition: all 0.25s ease-out;
+      -moz-transition: all 0.25s ease-out;
+       -ms-transition: all 0.25s ease-out;
+        -o-transition: all 0.25s ease-out;
+           transition: all 0.25s ease-out;
+
+}
+
+#header-wrap.quicknav {
+  height:170px;
+  
+}
+
+/* SEARCH AND MORE */
+.search {
+  position: absolute;
+  width: 50px;
+  height:28px;
+  display: block;
+  margin-top:-3px;
+  margin-bottom:7px;
+  overflow:hidden;
+  z-index:100;
+  right:54px;
+  -webkit-transition: width 0.4s ease;
+     -moz-transition: width 0.4s ease;
+       -o-transition: width 0.4s ease;
+          transition: width 0.4s ease;
+}
+
+.search #search-btn {
+  width:50px;
+  height:28px;
+  background:url(../images/icon_search.png) no-repeat;
+  float:left;
+}
+
+.search-inner {
+  width:245px;
+}
+
+.search:hover, .search.active {
+  width:245px;
+}
+
+.search .bottom, .search .left, .search .right {
+	position: absolute;
+	background-color: #a2a2a2
+}
+
+.search .bottom {
+	width: 214px;
+	height: 1px;
+	top: 24px;
+	left: 0
+}
+
+.search .left, .search .right {	
+	height: 5px;
+	width: 1px
+}
+
+.search .left {
+  top: 22px;
+  left: 56px;
+  background-color:#CCC;
+}
+
+.search .right {
+  top: 22px;
+  left: 238px;
+  background-color:#CCC;
+}
+
+.search form {
+	margin-top: 2px;
+	width: 162px;
+	float:left;
+}
+
+.search form input {
+	color: #2f2f2f;
+	font-size: 0.95em;
+	width: 178px;  
+	border: none;
+	margin-left: 6px;  
+	z-index: 1500;  
+  position: relative;
+	background-color: transparent;
+	border-bottom:1px solid #CCC;
+	padding:0 0 0 4px;
+	outline:none;
+	height:24px;
+}
+
+.search:hover form input {
+  border-bottom:1px solid #33B5E5;
+}
+
+.search:hover .bottom, .search:hover .left, .search:hover .right {
+	background-color: #33b5e5;
+}
+
+.search:hover #search-btn {
+	background-position: 0 -28px
+}
+
+.search form input:focus {
+	color: #222;
+	font-weight: bold
+}
+
+.moremenu {
+  float: right;
+	position: relative;
+	width: 50px;
+	height:28px;
+  display: block;
+  margin-top:-3px;
+  margin-bottom:7px;
+  overflow:hidden;
+  -webkit-transition: width 0.25s ease;
+     -moz-transition: width 0.25s ease;
+       -o-transition: width 0.25s ease;
+          transition: width 0.25s ease;
+}
+
+.moremenu #more-btn {
+  width:40px;
+  height:28px;
+  background:url(../images/icon_more.png) no-repeat;
+  border-left:1px solid #CCC;
+  float:left;
+  cursor:pointer;
+}
+
+.moremenu:hover #more-btn {
+  background-position:0 -28px;
+}
+
+.morehover {
+  position:absolute;
+  right:6px;
+  top:-9px;
+  width:40px;
+  height:35px;
+  z-index:99;
+  overflow:hidden;
+
+  -webkit-opacity:0;
+     -moz-opacity:0;
+       -o-opacity:0;
+          opacity:0;
+
+  -webkit-transform-origin:100% 0%;
+     -moz-transform-origin:100% 0%; 
+       -o-transform-origin:100% 0%;
+          transform-origin:100% 0%;
+  
+  -webkit-transition-property: -webkit-opacity;
+  -webkit-transition-duration: .25s;
+  -webkit-transition-timing-function:ease;
+
+  -moz-transition-property: -webkit-opacity;
+  -moz-transition-duration: .25s;
+  -moz-transition-timing-function:ease;
+
+  -o-transition-property: -webkit-opacity;
+  -o-transition-duration: .25s;
+  -o-transition-timing-function:ease;
+  
+  -transition-property: -webkit-opacity;
+  -transition-duration: .25s;
+  -transition-timing-function:ease;
+}
+
+.morehover:hover {
+  opacity:1;
+  height:345px;
+  width:268px;
+  -webkit-transition-property:height,  -webkit-opacity;
+}
+
+.morehover .top {
+  width:268px;
+  height:39px;
+  background:url(../images/more_top.png) no-repeat;
+}
+
+.morehover .mid {
+  width:228px;
+  background:url(../images/more_mid.png) repeat-y;
+  padding:10px 20px 10px 20px;
+}
+
+.morehover .mid .header {
+  border-bottom:1px solid #ccc;
+  font-weight:bold;
+}
+
+.morehover .bottom {
+  width:268px;
+  height:6px;
+  background:url(../images/more_bottom.png) no-repeat;
+}
+
+.morehover ul {
+  margin:10px 10px 20px 0;
+}
+
+.morehover ul li {
+  list-style:none;
+}
+
+.morehover ul li.active a,
+.morehover ul li.active a:hover {
+  color:#222 !important;
+}
+
+.morehover ul li.active img {
+  margin-right:4px;
+}
+
+
+
+
+/* MARQUEE */
+.slideshow-container {
+	width:100%;
+	overflow:hidden;
+	position:relative;
+}
+.slideshow-container .slideshow-prev {
+	position:absolute;
+	top:50%;
+	left:0px;
+	margin-top:-36px;
+	z-index:99;
+}
+.slideshow-container .slideshow-next {
+	position:absolute;
+	top:50%;
+	margin-top:-36px;
+	z-index:99;
+	right:0px;
+}
+
+.slideshow-container .pagination {
+	position:absolute;
+	bottom:20px;
+	width:100%;
+	text-align:center;
+	z-index:99;
+}
+.slideshow-container .pagination ul {
+	margin:0;
+}
+.slideshow-container .pagination ul li{
+	display: inline-block;
+	width:12px;
+	height:12px;
+	text-indent:-8000px;
+	list-style:none;
+	margin: 0 2px;
+	border-radius:6px;
+	background-color:#ccc;
+	cursor:pointer;
+        -webkit-transition:color .5s ease-in;  
+        -moz-transition:color .5s ease-in;  
+        -o-transition:color .5s ease-in;  
+        transition:color .5s ease-in;
+}
+.slideshow-container .pagination ul li:hover {
+	background-color:#999;
+}
+.slideshow-container .pagination ul li.active {
+	background-color:#33b5e5;
+}
+.slideshow-container .pagination ul li.active:hover {
+	background-color:#33b5e5;
+}
+.slideshow-container ul li {
+	display:inline;
+	list-style:none;
+}
+
+
+
+
+a.download-sdk {
+    float:right;
+    margin:-10px 0;
+    height:30px;
+    padding-top:4px;
+    padding-bottom:0px;
+}
+
+#nav-x {
+  padding-top: 14px;
+}
+
+#nav-x .wrap,
+#searchResults.wrap {
+    max-width:940px;
+    border-bottom:1px solid #CCC;
+    min-height:34px;
+    
+}
+
+
+.nav-x {
+    margin-left:0;
+    margin-bottom:0;
+}
+
+
+
+
+
+
+
+
+
+
+/*
+ * CSS Styles that are needed by jScrollPane for it to operate correctly.
+ */
+
+.jspContainer {
+  overflow: hidden;
+  position: relative;
+}
+
+.jspPane {
+  position: absolute;
+  overflow: hidden;
+  width:auto !important; /* to avoid cut-off api names in reference in horiz scroll */
+}
+
+.jspVerticalBar {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 4px;
+  height: 100%;
+  background: #f5f5f5;
+}
+
+.jspHorizontalBar {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 4px;
+  background: #f5f5f5;
+}
+
+.jspVerticalBar *,
+.jspHorizontalBar * {
+  margin: 0;
+  padding: 0;
+}
+.jspCap {
+  display: block;
+}
+
+.jspVerticalBar .jspCap {
+  height: 4px;
+}
+
+.jspHorizontalBar .jspCap {
+  width: 0;
+  height: 100%;
+}
+
+.jspHorizontalBar .jspCap {
+  float: left;
+}
+
+.jspTrack {
+  position: relative;
+}
+
+.jspDrag {
+  background: #bbb;
+  position: relative;
+  top: 0;
+  left: 0;
+  cursor: pointer;
+}
+
+.jspDrag:hover,
+.jspDrag:active {
+  border-color: #09c;
+  background-color: #4cadcb;
+  background-image: -webkit-gradient(linear, left top, right top, from(#5dbcd9), to(#4cadcb));
+  background-image: -webkit-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -moz-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -ms-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: -o-linear-gradient(left, #5dbcd9, #4cadcb);
+  background-image: linear-gradient(left, #5dbcd9, #4cadcb);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5dbcd9', EndColorStr='#4cadcb');	
+}
+
+.jspHorizontalBar .jspTrack,
+.jspHorizontalBar .jspDrag {
+  float: left;
+  height: 100%;
+}
+
+.jspArrow {
+  background: #999;
+  text-indent: -20000px;
+  display: block;
+  cursor: pointer;
+}
+
+.jspArrow.jspDisabled {
+  cursor: default;
+  background: #ccc;
+}
+
+.jspVerticalBar .jspArrow {
+  height: 16px;
+}
+
+.jspHorizontalBar .jspArrow {
+  width: 16px;
+  float: left;
+  height: 100%;
+}
+
+.jspVerticalBar .jspArrow:focus {
+  outline: none;
+}
+
+.jspCorner {
+  float: left;
+  height: 100%;
+}
+
+/* Yuk! CSS Hack for IE6 3 pixel bug :( */
+* html .jspCorner {
+  margin: 0 -3px 0 0;
+}
+/******* end of jscrollpane *********/
+
+
+
+
+
+/************ DEVELOP HOMEPAGE ******************/
+
+/* Slideshow */
+.slideshow-develop {
+  height: 300px;
+  width: 940px;
+  position: relative;
+  overflow:hidden;
+}
+.slideshow-develop .frame {
+  width: 940px;
+  height: 300px;
+}
+.slideshow-develop img.play {
+  width:350px;
+  margin:20px 0 0 90px;
+  -webkit-transform: perspective(800px ) rotateY( 35deg );
+  box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+  -moz-box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+  -webkit-box-shadow: -16px 20px 40px rgba(0, 0, 0, 0.3);
+}
+.slideshow-develop img.play.no-shadow {
+    box-shadow: none;
+    -moz-box-shadow: none;
+    -webkit-box-shadow: none;
+}
+.slideshow-develop img.play.no-transform {
+  -webkit-transform: none;
+}
+.slideshow-develop a.slideshow-next {
+  background: url(../images/arrow-right-develop.png);
+}
+.slideshow-develop a.slideshow-prev {
+  background: url(../images/arrow-left-develop.png);
+}
+.slideshow-develop .content-right {
+  float: left;
+}
+.slideshow-develop .content-right p.title-intro {
+  position:absolute;
+  margin:0;
+}
+.slideshow-develop .content-right h2 {
+  padding:0;
+  margin-bottom:10px;
+  border:none;
+}
+.slideshow-develop .item {
+  height: 300px;
+  width: 940px;
+}
+.slideshow-develop .pagination ul li.active {
+  background-color: #F80;
+}
+.slideshow-develop .pagination ul li.active:hover {
+  background-color: #F80;
+}
+
+/* Feeds */
+.feed ul {
+  margin: 0;
+}
+.feed .feed-nav {
+  height: 25px;
+  border-bottom: 1px solid #CCC;
+}
+.feed .feed-nav li {
+  list-style: none;
+  float: left;
+  margin-right: 25px;
+  cursor: pointer;
+}
+.feed .feed-nav li.active {
+  color: #000;
+  border-bottom: 4px solid #F80;
+}
+.feed .feed-container {
+  overflow: hidden;
+  width: 460px;
+}
+.feed .feed-container .feed-frame {
+  width: 1000px;
+}
+.feed .feed-container .feed-frame ul {
+  float: left;
+  width:460px;
+}
+.feed .feed-container .feed-frame ul ul {
+  float: none;
+  margin:10px 0 0 30px;
+}
+.feed .feed-container .feed-frame li {
+  list-style: none;
+  margin: 20px 0 20px 0;
+  width: 460px;
+  height:93px;
+}
+.feed .feed-container .feed-frame li.playlist {
+  height:auto;
+}
+.feed .feed-container .feed-frame li.playlist a {
+  height:93px;
+  display:block;
+}
+.feed .feed-container .feed-frame li.more {
+  height:20px;
+  margin:10px 0 5px 5px;
+}
+.feed .feed-container .feed-frame li.more a {
+  height:inherit;
+}
+.feed .feed-container .feed-frame li.playlist-video {
+  list-style: none;
+  margin: 0;
+  width: 460px;
+  height:55px;
+  font-size:12px;
+}
+.feed .feed-container .feed-frame li.playlist-video a {
+  height:45px;
+  padding:5px;
+}
+.feed .feed-container .feed-frame li.playlist-video h5 {
+  font-size:12px;
+  line-height:13px;
+  margin:0;
+}
+.feed .feed-container .feed-frame li.playlist-video p {
+  margin:5px 0 0;
+  line-height:15px;
+}
+.feed-container .feed-frame div.feed-image {
+  float: left;
+  border: 1px solid #999;
+  margin:0 20px 0 0;
+  width:122px;
+  height:92px;
+  background:url('../images/blog-default.png') no-repeat 0 0;
+  background-size:180px;
+}
+#jd-content .feed .feed-container .feed-frame li img {
+  float: left;
+  border: 1px solid #999;
+  margin:0 20px 0 0;
+  width:122px;
+  height:92px;
+}
+#jd-content .feed .feed-container .feed-frame li.playlist-video img {
+  width:inherit;
+  height:inherit;
+}
+
+.feed .feed-container .feed-frame li a,
+.feed .feed-container .feed-frame li a:active {
+  color:#555 !important;
+}
+
+.feed .feed-container .feed-frame li a:hover,
+.feed .feed-container .feed-frame li a:hover * {
+  color:#7AA1B0 !important;
+}
+
+/* Video player */
+#player-wrapper {
+  display:none;
+  margin: -1px auto 0;
+  position: relative;
+  width: 940px;
+  height: 0px;
+}
+#player-frame {
+  background: #EFEFEF;
+  border: 1px solid #CCC;
+  padding: 0px 207px;
+  z-index: 10; /* stay above marque, but below search suggestions */
+  width: 525px;
+  height: 330px;
+  position: relative;
+}
+
+
+
+/************ DISTRIBUTE HOMEPAGE ***************/
+
+.marquee {
+  width: 760px;
+}
+.marquee .main-img {
+  float: left;
+  margin-top: 20px;
+  width: 490px;
+}
+.marquee .copy {
+  width: 270px;
+  float: left;
+  margin-top: 30px;
+}
+.distribute-features {
+  margin: 0;
+}
+.distribute-features ul {
+  margin: 0;
+}
+.distribute-features ul li {
+  list-style: none;
+  float: left;
+  border-top: 1px solid #9C0;
+  width: 220px;
+  margin-right: 50px;
+}
+.distribute-features ul li.last {
+  margin-right: 0px;
+}
+
+
+/************ DEVELOP TOPIC CONTAINERS ************/
+
+.landing-banner,
+.landing-docs {
+  margin:20px 0 0;
+}
+.landing-banner {
+  height:280px;
+}
+.landing-banner .col-6:first-child,
+.landing-docs .col-6:first-child {
+  margin-left:0;
+}
+.landing-banner .col-6:last-child,
+.landing-docs .col-6:last-child {
+  margin-right:0;
+}
+
+.landing-banner h1 {
+  margin-top:0;
+}
+.landing-docs h3 {
+  font-size:14px;
+  line-height:21px;
+  color:#555;
+  text-transform:uppercase;
+  border-bottom:1px solid #CCC;
+  margin:0 0 20px;
+}
+.landing-docs a {
+  color:#333 !important;
+}
+.landing-docs a:hover,
+.landing-docs a:hover * {
+  color:#7AA1B0 !important
+}
+
+.plusone {
+  float:right;
+}
\ No newline at end of file
diff --git a/docs/html/guide/google/gcm/server-javadoc/deprecated-list.html b/docs/html/guide/google/gcm/server-javadoc/deprecated-list.html
index 0082614..729b2bf 100644
--- a/docs/html/guide/google/gcm/server-javadoc/deprecated-list.html
+++ b/docs/html/guide/google/gcm/server-javadoc/deprecated-list.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Deprecated List
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/help-doc.html b/docs/html/guide/google/gcm/server-javadoc/help-doc.html
index 72f9fb2..7f5286c 100644
--- a/docs/html/guide/google/gcm/server-javadoc/help-doc.html
+++ b/docs/html/guide/google/gcm/server-javadoc/help-doc.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 API Help
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/index-all.html b/docs/html/guide/google/gcm/server-javadoc/index-all.html
index e6325cb..0b095ec 100644
--- a/docs/html/guide/google/gcm/server-javadoc/index-all.html
+++ b/docs/html/guide/google/gcm/server-javadoc/index-all.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Index
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="./stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="./default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
@@ -121,9 +121,16 @@
 <DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_DEVICE_QUOTA_EXCEEDED"><B>ERROR_DEVICE_QUOTA_EXCEEDED</B></A> - 
 Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
 <DD>Too many messages sent by the sender to a specific device.
+<DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_INTERNAL_SERVER_ERROR"><B>ERROR_INTERNAL_SERVER_ERROR</B></A> - 
+Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
+<DD>A particular message could not be sent because the GCM servers encountered
+ an error.
 <DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_INVALID_REGISTRATION"><B>ERROR_INVALID_REGISTRATION</B></A> - 
 Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
 <DD>Bad registration_id.
+<DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_INVALID_TTL"><B>ERROR_INVALID_TTL</B></A> - 
+Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
+<DD>Time to Live value passed is less than zero or more than maximum.
 <DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_MESSAGE_TOO_BIG"><B>ERROR_MESSAGE_TOO_BIG</B></A> - 
 Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
 <DD>The payload of the message is too big, see the limitations.
@@ -145,8 +152,8 @@
 <DD>Too many messages sent by the sender.
 <DT><A HREF="./com/google/android/gcm/server/Constants.html#ERROR_UNAVAILABLE"><B>ERROR_UNAVAILABLE</B></A> - 
 Static variable in class com.google.android.gcm.server.<A HREF="./com/google/android/gcm/server/Constants.html" title="class in com.google.android.gcm.server">Constants</A>
-<DD>Used to indicate that a particular message could not be sent because
- the GCM servers were not available.
+<DD>A particular message could not be sent because the GCM servers were not
+ available.
 </DL>
 <HR>
 <A NAME="_G_"><!-- --></A><H2>
diff --git a/docs/html/guide/google/gcm/server-javadoc/index.html b/docs/html/guide/google/gcm/server-javadoc/index.html
index efcce9e..d8ba0ef 100644
--- a/docs/html/guide/google/gcm/server-javadoc/index.html
+++ b/docs/html/guide/google/gcm/server-javadoc/index.html
@@ -2,7 +2,7 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc on Thu Jun 21 12:04:57 PDT 2012-->
+<!-- Generated by javadoc on Mon Jul 16 14:12:10 PDT 2012-->
 <TITLE>
 Generated Documentation (Untitled)
 </TITLE>
diff --git a/docs/html/guide/google/gcm/server-javadoc/overview-tree.html b/docs/html/guide/google/gcm/server-javadoc/overview-tree.html
index 034838b..b8e28ad 100644
--- a/docs/html/guide/google/gcm/server-javadoc/overview-tree.html
+++ b/docs/html/guide/google/gcm/server-javadoc/overview-tree.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Class Hierarchy
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/gcm/server-javadoc/serialized-form.html b/docs/html/guide/google/gcm/server-javadoc/serialized-form.html
index 86cd61a..7a1378f 100644
--- a/docs/html/guide/google/gcm/server-javadoc/serialized-form.html
+++ b/docs/html/guide/google/gcm/server-javadoc/serialized-form.html
@@ -2,14 +2,14 @@
 <!--NewPage-->
 <HTML>
 <HEAD>
-<!-- Generated by javadoc (build 1.6.0_20) on Thu Jun 21 12:04:57 PDT 2012 -->
+<!-- Generated by javadoc (build 1.6.0_26) on Mon Jul 16 14:12:10 PDT 2012 -->
 <TITLE>
 Serialized Form
 </TITLE>
 
-<META NAME="date" CONTENT="2012-06-21">
+<META NAME="date" CONTENT="2012-07-16">
 
-<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="default.css" TITLE="Style">
 
 <SCRIPT type="text/javascript">
 function windowTitle()
diff --git a/docs/html/guide/google/play/billing/billing_overview.jd b/docs/html/guide/google/play/billing/billing_overview.jd
index 05139b4..82f6cf4 100755
--- a/docs/html/guide/google/play/billing/billing_overview.jd
+++ b/docs/html/guide/google/play/billing/billing_overview.jd
@@ -353,8 +353,9 @@
 
 <p>The <code>RESTORE_TRANSACTIONS</code> request type also triggers a
 <code>PURCHASE_STATE_CHANGED</code> broadcast intent, which contains the same type of transaction
-information that is sent during a purchase request, although you do not need to respond to this
-intent with a <code>CONFIRM_NOTIFICATIONS</code> message.</p>
+information that is sent during a purchase request. Unlike with a purchase request, however, the transactions
+are given without any associated notification IDs, so you do not need to respond to this
+intent with a <code>CONFIRM_NOTIFICATIONS</code> message. </p>
 
 <p class="note"><strong>Note:</strong> You should use the <code>RESTORE_TRANSACTIONS</code> request
 type only when your application is installed for the first time on a device or when your
diff --git a/docs/html/guide/google/play/billing/billing_reference.jd b/docs/html/guide/google/play/billing/billing_reference.jd
index f8c6967..c5541fa 100755
--- a/docs/html/guide/google/play/billing/billing_reference.jd
+++ b/docs/html/guide/google/play/billing/billing_reference.jd
@@ -450,9 +450,7 @@
 <p>The In-app Billing API is versioned, with each version offering
 additional features to your app. At run time, your app can query the Google Play app to determine
 what version of the API it supports and what features are available. Typically, the Google Play app
-will be updated and will support the latest version of the API. For a summary of versions see
-<a href="{@docRoot}guide/google/play/billing/billing_reference.html#billing-versions">In-app Billing
-API Versions</a>.</p>
+will be updated and will support the latest version of the API. 
 
 <p>The sections below list the supported versions of the In-app Billing API.
 Versions are specified in the <code>API_VERSION</code> key of the Bundle object
diff --git a/docs/html/guide/google/play/billing/billing_subscriptions.jd b/docs/html/guide/google/play/billing/billing_subscriptions.jd
index 3cf9777..ae12951 100755
--- a/docs/html/guide/google/play/billing/billing_subscriptions.jd
+++ b/docs/html/guide/google/play/billing/billing_subscriptions.jd
@@ -241,9 +241,10 @@
 it to validate or cancel the subscription remotely using the <a
 href="#play-dev-api">Google Play Android Developer API</a>.</p>
 
-<p>In the case of billing errors, such as could happen if the customer’s credit
-card becomes invalid, Google Play notifies your app of the change in purchase
-state.</p>
+<p>If a recurring payment fails, such as could happen if the customer’s credit
+card has become invalid, the subscription does not renew. Google Play notifies your
+app at the end of the active cycle that the purchase state of the subscription is now "Expired".
+Your app does not need to grant the user further access to the subscription content.</p>
 
 <p>As a best practice, we recommend that your app includes business logic to
 notify your backend servers of subscription purchases, tokens, and any billing
@@ -626,13 +627,13 @@
 content.</p>
 
 <p>With In-app Billing, you validate a subscription by keeping track of its
-purchase state, such as purchased or cancelled, and then checking the state
-whenever needed. Google Play provides two ways to let you know when the purchase
+purchase state and then checking the state whenever needed. Google Play 
+provides two ways to let you know when the purchase
 state of a subscription changes:</p>
 
 <ul>
   <li><em>In-app Billing Notifications</em>. Google Play pushes a notification
-  to your app whenever  the purchase state of a subscription changes. Your app can
+  to your app to indicate a change in the purchase state of a subscription. Your app can
   store the most recent purchase state for a given purchase token and then check
   that state at run time, as needed.</li>
   <li><em>Google Play Android Developer API</em>. You can use this HTTP-based
@@ -689,7 +690,8 @@
 <td>Purchased successfully</td><td><code>0</code></td><td>Sent at original purchase only (not at recurring billing cycles).</td></tr>
 <td>Cancelled</td><td><code>1</code></td><td>Sent at original purchase only if the purchase has failed for some reason. </td></tr>
 <td>Refunded</td><td><code>2</code></td><td>The purchase was refunded.</code></td></tr>
-<td>Subscription expired</td><td><code>3</code></td><td>Sent if a subscription expires because of non-payment or user cancelation.</td></tr>
+<td>Subscription expired</td><td><code>3</code></td><td>Sent at the end of a billing cycle to indicate that the subscription expired without renewal because of non-payment or user-cancellation. Your app does not need to grant continued access to the subscription content. 
+</td></tr>
 </table>
 
 
@@ -718,7 +720,7 @@
 <p>For more information, see 
   <a href="{@docRoot}distribute/googleplay/promote/linking.html">Linking to Your Products</a>.</p>
 
-<h3 id="purchase-state-changes">Recurring billing and changes in purchase state</h3>
+<h3 id="purchase-state-changes">Recurring billing, cancellation, and changes in purchase state</h3>
 
 <p>Google Play notifies your app when the user completes the purchase of a
 subscription, but the purchase state does not change over time, provided that
@@ -730,6 +732,19 @@
 recurring billing events &mdash; those are all handled by Google Play and they
 are transparent to your application if billing is successful.</p>
 
+<p>When the user cancels a subscription during an active billing cycle, Google
+Play <em>does not</em> notify your app immediately of the change in purchase
+state. Instead, it waits until the end of the active billing cycle and then
+notifies your app that the purchase state has changed to "Expired". </p>
+
+<p>Similarly, if payment for the next billing cycle fails, Google Play waits
+until the end of the active billing cycle and then notifies your app at that time that the
+purchase state has changed to "Expired".</p>
+
+<p>Your app can handle user cancellation and non-payment in the same way, since both cause
+a change to the same "Expired" purchase state. Once the purchase state has become "Expired",
+your app does not need to grant further access to the subscription content.</p>
+
 <h3 id="modifying">Modifying your app for subscriptions</h3>
 
 <p>For subscriptions, you make the same types of modifications to your app as
diff --git a/docs/html/guide/practices/performance.jd b/docs/html/guide/practices/performance.jd
index 078999b..3e2714c 100644
--- a/docs/html/guide/practices/performance.jd
+++ b/docs/html/guide/practices/performance.jd
@@ -168,20 +168,23 @@
 usually inline the access, and if you need to restrict or debug field access
 you can add the code at any time.</p>
 
-<p>On Android, this is a bad idea.  Virtual method calls are expensive,
-much more so than instance field lookups.  It's reasonable to follow
+<p>On Android, this can be a bad idea.  Virtual method calls can be more
+expensive than instance field lookups.  It's reasonable to follow
 common object-oriented programming practices and have getters and setters
-in the public interface, but within a class you should always access
+in the public interface, but within a class you might want to access
 fields directly.</p>
 
 <p>Without a JIT, direct field access is about 3x faster than invoking a
-trivial getter. With the JIT (where direct field access is as cheap as
-accessing a local), direct field access is about 7x faster than invoking a
-trivial getter. This is true in Froyo, but will improve in the future when
-the JIT inlines getter methods.</p>
+trivial getter (one that simply returns the value of a field, without
+any dereferencing or array indexing). With the Froyo JIT, direct field
+access was about 7x faster than invoking a trivial getter. Since
+Gingerbread, though, the JIT inlines trivial getter methods, making
+that particular optimization obsolete. Manual inlining guided by
+profiling can still be a useful technique in general, though.</a>
 
 <p>Note that if you're using ProGuard, you can have the best
-of both worlds because ProGuard can inline accessors for you.</p>
+of both worlds even with non-trival accessors, because ProGuard can inline
+for you.</p>
 
 <a name="use_final" id="use_final"></a>
 <h2>Use Static Final For Constants</h2>
diff --git a/docs/html/sdk/api_diff/16/changes.html b/docs/html/sdk/api_diff/16/changes.html
index 80b91e4..6460252 100644
--- a/docs/html/sdk/api_diff/16/changes.html
+++ b/docs/html/sdk/api_diff/16/changes.html
@@ -4,7 +4,7 @@
 <meta name="generator" content="JDiff v1.1.0">
 <!-- Generated by the JDiff Javadoc doclet -->
 <!-- (http://www.jdiff.org) -->
-<!-- on Tue Jun 26 22:31:04 PDT 2012 -->
+<!-- on Mon Jul 16 10:58:42 PDT 2012 -->
 <meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
 <meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
 <TITLE>
diff --git a/docs/html/sdk/api_diff/16/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/16/changes/alldiffs_index_additions.html
index 66ecf7d..d47f571 100644
--- a/docs/html/sdk/api_diff/16/changes/alldiffs_index_additions.html
+++ b/docs/html/sdk/api_diff/16/changes/alldiffs_index_additions.html
@@ -152,6 +152,8 @@
 <!-- Field ACTION_VOICE_SEARCH_HANDS_FREE -->
 <nobr><A HREF="android.speech.RecognizerIntent.html#android.speech.RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE" class="hiddenlink" target="rightframe">ACTION_VOICE_SEARCH_HANDS_FREE</A>
 </nobr><br>
+<!-- Class ActionProvider.VisibilityListener -->
+<A HREF="pkg_android.view.html#ActionProvider.VisibilityListener" class="hiddenlink" target="rightframe"><b><i>ActionProvider.VisibilityListener</i></b></A><br>
 <!-- Class ActivityOptions -->
 <A HREF="pkg_android.app.html#ActivityOptions" class="hiddenlink" target="rightframe"><b>ActivityOptions</b></A><br>
 <!-- Method addAction -->
@@ -543,9 +545,6 @@
 <!-- Method finishAffinity -->
 <nobr><A HREF="android.app.Activity.html#android.app.Activity.finishAffinity_added()" class="hiddenlink" target="rightframe"><b>finishAffinity</b>
 ()</A></nobr><br>
-<!-- Field FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS -->
-<nobr><A HREF="android.content.Intent.html#android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS" class="hiddenlink" target="rightframe">FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS</A>
-</nobr><br>
 <!-- Field FLAG_INCLUDE_NOT_IMPORTANT_VIEWS -->
 <nobr><A HREF="android.accessibilityservice.AccessibilityServiceInfo.html#android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS" class="hiddenlink" target="rightframe">FLAG_INCLUDE_NOT_IMPORTANT_VIEWS</A>
 </nobr><br>
@@ -1262,6 +1261,9 @@
 <!-- Method isVirtual -->
 <nobr><A HREF="android.view.InputDevice.html#android.view.InputDevice.isVirtual_added()" class="hiddenlink" target="rightframe"><b>isVirtual</b>
 ()</A></nobr><br>
+<!-- Method isVisible -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.isVisible_added()" class="hiddenlink" target="rightframe"><b>isVisible</b>
+()</A></nobr><br>
 <!-- Method isVisibleToUser -->
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.isVisibleToUser_added()" class="hiddenlink" target="rightframe"><b>isVisibleToUser</b>
 ()</A></nobr><br>
@@ -1472,6 +1474,11 @@
 <A HREF="pkg_android.media.html#MediaRouter.SimpleCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.SimpleCallback</b></A><br>
 <!-- Class MediaRouter.UserRouteInfo -->
 <A HREF="pkg_android.media.html#MediaRouter.UserRouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.UserRouteInfo</b></A><br>
+<!-- Class MediaRouter.VolumeCallback -->
+<A HREF="pkg_android.media.html#MediaRouter.VolumeCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.VolumeCallback</b></A><br>
+<!-- Field mediaRouteTypes -->
+<nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteTypes" class="hiddenlink" target="rightframe">mediaRouteTypes</A>
+</nobr><br>
 <!-- Class MediaSyncEvent -->
 <A HREF="pkg_android.media.html#MediaSyncEvent" class="hiddenlink" target="rightframe"><b>MediaSyncEvent</b></A><br>
 <!-- Field METHOD_ALARM -->
@@ -1660,6 +1667,9 @@
 <!-- Field OPTION_APPWIDGET_MIN_WIDTH -->
 <nobr><A HREF="android.appwidget.AppWidgetManager.html#android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH" class="hiddenlink" target="rightframe">OPTION_APPWIDGET_MIN_WIDTH</A>
 </nobr><br>
+<!-- Method overridesItemVisibility -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.overridesItemVisibility_added()" class="hiddenlink" target="rightframe"><b>overridesItemVisibility</b>
+()</A></nobr><br>
 <!-- Field parentActivityName -->
 <A NAME="P"></A>
 <br><font size="+2">P</font>&nbsp;
@@ -1846,6 +1856,9 @@
 <!-- Field READ_USER_DICTIONARY -->
 <nobr><A HREF="android.Manifest.permission.html#android.Manifest.permission.READ_USER_DICTIONARY" class="hiddenlink" target="rightframe">READ_USER_DICTIONARY</A>
 </nobr><br>
+<!-- Method refreshVisibility -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.refreshVisibility_added()" class="hiddenlink" target="rightframe"><b>refreshVisibility</b>
+()</A></nobr><br>
 <!-- Method registerOnLoadCanceledListener -->
 <nobr><A HREF="android.content.Loader.html#android.content.Loader.registerOnLoadCanceledListener_added(android.content.Loader.OnLoadCanceledListener<D>)" class="hiddenlink" target="rightframe"><b>registerOnLoadCanceledListener</b>
 (<code>OnLoadCanceledListener&lt;D&gt;</code>)</A></nobr><br>
@@ -2105,6 +2118,12 @@
 <!-- Method setTextViewCompoundDrawables -->
 <nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawables_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawables</b>
 (<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setTextViewCompoundDrawablesRelative -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawablesRelative</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setTextViewTextSize -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)" class="hiddenlink" target="rightframe"><b>setTextViewTextSize</b>
+(<code>int, int, float</code>)</A></nobr><br>
 <!-- Method setThumbDrawable -->
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbDrawable_added(android.graphics.drawable.Drawable)" class="hiddenlink" target="rightframe"><b>setThumbDrawable</b>
 (<code>Drawable</code>)</A></nobr><br>
@@ -2141,6 +2160,12 @@
 <!-- Method setVideoScalingMode -->
 <nobr><A HREF="android.media.MediaPlayer.html#android.media.MediaPlayer.setVideoScalingMode_added(int)" class="hiddenlink" target="rightframe"><b>setVideoScalingMode</b>
 (<code>int</code>)</A></nobr><br>
+<!-- Method setViewPadding -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setViewPadding</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setVisibilityListener -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)" class="hiddenlink" target="rightframe"><b>setVisibilityListener</b>
+(<code>VisibilityListener</code>)</A></nobr><br>
 <!-- Method setVisibleToUser -->
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.setVisibleToUser_added(boolean)" class="hiddenlink" target="rightframe"><b>setVisibleToUser</b>
 (<code>boolean</code>)</A></nobr><br>
diff --git a/docs/html/sdk/api_diff/16/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/16/changes/alldiffs_index_all.html
index b4e7d1d..02c78b4 100644
--- a/docs/html/sdk/api_diff/16/changes/alldiffs_index_all.html
+++ b/docs/html/sdk/api_diff/16/changes/alldiffs_index_all.html
@@ -178,6 +178,8 @@
 <A HREF="android.view.ActionMode.html" class="hiddenlink" target="rightframe">ActionMode</A><br>
 <!-- Class ActionProvider -->
 <A HREF="android.view.ActionProvider.html" class="hiddenlink" target="rightframe">ActionProvider</A><br>
+<!-- Class ActionProvider.VisibilityListener -->
+<A HREF="pkg_android.view.html#ActionProvider.VisibilityListener" class="hiddenlink" target="rightframe"><b><i>ActionProvider.VisibilityListener</i></b></A><br>
 <!-- Class Activity -->
 <A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
 <!-- Class ActivityInfo -->
@@ -1083,9 +1085,6 @@
 <!-- Method fitsSystemWindows -->
 <nobr><A HREF="android.view.View.html#android.view.View.fitsSystemWindows_removed()" class="hiddenlink" target="rightframe"><strike>fitsSystemWindows</strike>
 ()</A></nobr><br>
-<!-- Field FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS -->
-<nobr><A HREF="android.content.Intent.html#android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS" class="hiddenlink" target="rightframe">FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS</A>
-</nobr><br>
 <!-- Field FLAG_HIGH_PRIORITY -->
 <nobr><A HREF="android.app.Notification.html#android.app.Notification.FLAG_HIGH_PRIORITY" class="hiddenlink" target="rightframe">FLAG_HIGH_PRIORITY</A>
 </nobr><br>
@@ -1986,6 +1985,9 @@
 <!-- Method isVirtual -->
 <nobr><A HREF="android.view.InputDevice.html#android.view.InputDevice.isVirtual_added()" class="hiddenlink" target="rightframe"><b>isVirtual</b>
 ()</A></nobr><br>
+<!-- Method isVisible -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.isVisible_added()" class="hiddenlink" target="rightframe"><b>isVisible</b>
+()</A></nobr><br>
 <!-- Method isVisibleToUser -->
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.isVisibleToUser_added()" class="hiddenlink" target="rightframe"><b>isVisibleToUser</b>
 ()</A></nobr><br>
@@ -2264,6 +2266,11 @@
 <A HREF="pkg_android.media.html#MediaRouter.SimpleCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.SimpleCallback</b></A><br>
 <!-- Class MediaRouter.UserRouteInfo -->
 <A HREF="pkg_android.media.html#MediaRouter.UserRouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.UserRouteInfo</b></A><br>
+<!-- Class MediaRouter.VolumeCallback -->
+<A HREF="pkg_android.media.html#MediaRouter.VolumeCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.VolumeCallback</b></A><br>
+<!-- Field mediaRouteTypes -->
+<nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteTypes" class="hiddenlink" target="rightframe">mediaRouteTypes</A>
+</nobr><br>
 <!-- Class MediaStore.MediaColumns -->
 <A HREF="android.provider.MediaStore.MediaColumns.html" class="hiddenlink" target="rightframe"><i>MediaStore.MediaColumns</i></A><br>
 <!-- Class MediaSyncEvent -->
@@ -2560,6 +2567,9 @@
 <!-- Field ORIENTATION_SQUARE -->
 <nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.ORIENTATION_SQUARE" class="hiddenlink" target="rightframe">ORIENTATION_SQUARE</A>
 </nobr><br>
+<!-- Method overridesItemVisibility -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.overridesItemVisibility_added()" class="hiddenlink" target="rightframe"><b>overridesItemVisibility</b>
+()</A></nobr><br>
 <!-- Class PackageInfo -->
 <A NAME="P"></A>
 <br><font size="+2">P</font>&nbsp;
@@ -2853,6 +2863,9 @@
 </nobr><br>
 <!-- Class RecognizerIntent -->
 <A HREF="android.speech.RecognizerIntent.html" class="hiddenlink" target="rightframe">RecognizerIntent</A><br>
+<!-- Method refreshVisibility -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.refreshVisibility_added()" class="hiddenlink" target="rightframe"><b>refreshVisibility</b>
+()</A></nobr><br>
 <!-- Method registerOnLoadCanceledListener -->
 <nobr><A HREF="android.content.Loader.html#android.content.Loader.registerOnLoadCanceledListener_added(android.content.Loader.OnLoadCanceledListener<D>)" class="hiddenlink" target="rightframe"><b>registerOnLoadCanceledListener</b>
 (<code>OnLoadCanceledListener&lt;D&gt;</code>)</A></nobr><br>
@@ -3321,6 +3334,12 @@
 <!-- Method setTextViewCompoundDrawables -->
 <nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawables_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawables</b>
 (<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setTextViewCompoundDrawablesRelative -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawablesRelative</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setTextViewTextSize -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)" class="hiddenlink" target="rightframe"><b>setTextViewTextSize</b>
+(<code>int, int, float</code>)</A></nobr><br>
 <!-- Method setThumbDrawable -->
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbDrawable_added(android.graphics.drawable.Drawable)" class="hiddenlink" target="rightframe"><b>setThumbDrawable</b>
 (<code>Drawable</code>)</A></nobr><br>
@@ -3369,6 +3388,12 @@
 <!-- Method setVideoScalingMode -->
 <nobr><A HREF="android.media.MediaPlayer.html#android.media.MediaPlayer.setVideoScalingMode_added(int)" class="hiddenlink" target="rightframe"><b>setVideoScalingMode</b>
 (<code>int</code>)</A></nobr><br>
+<!-- Method setViewPadding -->
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setViewPadding</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<!-- Method setVisibilityListener -->
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)" class="hiddenlink" target="rightframe"><b>setVisibilityListener</b>
+(<code>VisibilityListener</code>)</A></nobr><br>
 <!-- Method setVisibleToUser -->
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.setVisibleToUser_added(boolean)" class="hiddenlink" target="rightframe"><b>setVisibleToUser</b>
 (<code>boolean</code>)</A></nobr><br>
diff --git a/docs/html/sdk/api_diff/16/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/16/changes/android.Manifest.permission.html
index c7988c0..3ec476f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.Manifest.permission.html
+++ b/docs/html/sdk/api_diff/16/changes/android.Manifest.permission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.R.attr.html b/docs/html/sdk/api_diff/16/changes/android.R.attr.html
index 0d63d90..a4db7cf4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.R.attr.html
+++ b/docs/html/sdk/api_diff/16/changes/android.R.attr.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -119,6 +119,13 @@
 </TR>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.R.attr.mediaRouteTypes"></A>
+  <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.attr.html#mediaRouteTypes" target="_top"><code>mediaRouteTypes</code></A></nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="android.R.attr.parentActivityName"></A>
   <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.attr.html#parentActivityName" target="_top"><code>parentActivityName</code></A></nobr>
   </TD>
diff --git a/docs/html/sdk/api_diff/16/changes/android.R.style.html b/docs/html/sdk/api_diff/16/changes/android.R.style.html
index a9827b5..988463c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.R.style.html
+++ b/docs/html/sdk/api_diff/16/changes/android.R.style.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityService.html b/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityService.html
index e5da9e6..227ab96 100644
--- a/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityService.html
+++ b/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityService.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityServiceInfo.html b/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityServiceInfo.html
index 28ac08b..c5f3e7c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityServiceInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.accessibilityservice.AccessibilityServiceInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.animation.LayoutTransition.html b/docs/html/sdk/api_diff/16/changes/android.animation.LayoutTransition.html
index d3cc2f7..a170508 100644
--- a/docs/html/sdk/api_diff/16/changes/android.animation.LayoutTransition.html
+++ b/docs/html/sdk/api_diff/16/changes/android.animation.LayoutTransition.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.Activity.html b/docs/html/sdk/api_diff/16/changes/android.app.Activity.html
index 7532134..b15de59 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.Activity.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.Activity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.MemoryInfo.html b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.MemoryInfo.html
index f30b1da..99c8ca0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.MemoryInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.MemoryInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.RunningAppProcessInfo.html b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.RunningAppProcessInfo.html
index 0b7ebc7..041094e 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.RunningAppProcessInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.RunningAppProcessInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.html b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.html
index 1c91fc1..309551c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.ActivityManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.DownloadManager.Request.html b/docs/html/sdk/api_diff/16/changes/android.app.DownloadManager.Request.html
index 0b7d9b7..97f5b10 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.DownloadManager.Request.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.DownloadManager.Request.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.Fragment.html b/docs/html/sdk/api_diff/16/changes/android.app.Fragment.html
index bde4b96..d60cecb 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.Fragment.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.Fragment.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.KeyguardManager.html b/docs/html/sdk/api_diff/16/changes/android.app.KeyguardManager.html
index b90590a..dd6dd34 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.KeyguardManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.KeyguardManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.Notification.Builder.html b/docs/html/sdk/api_diff/16/changes/android.app.Notification.Builder.html
index 7ca6ba2..85d595a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.Notification.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.Notification.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.Notification.html b/docs/html/sdk/api_diff/16/changes/android.app.Notification.html
index 1bc971e..842bd39 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.Notification.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.Notification.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.PendingIntent.html b/docs/html/sdk/api_diff/16/changes/android.app.PendingIntent.html
index be25f30..d262768 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.PendingIntent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.PendingIntent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.SearchManager.html b/docs/html/sdk/api_diff/16/changes/android.app.SearchManager.html
index 1722f6e..285781e 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.SearchManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.SearchManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.app.WallpaperManager.html b/docs/html/sdk/api_diff/16/changes/android.app.WallpaperManager.html
index 59a3cee..1fb21b4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.app.WallpaperManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.app.WallpaperManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetHostView.html b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetHostView.html
index 0dc5304..be9f0c8 100644
--- a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetHostView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetHostView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetManager.html b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetManager.html
index e467c89..47b3c4a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetProvider.html b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetProvider.html
index 8aa8b9c..e8f677f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetProvider.html
+++ b/docs/html/sdk/api_diff/16/changes/android.appwidget.AppWidgetProvider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.bluetooth.BluetoothAdapter.html b/docs/html/sdk/api_diff/16/changes/android.bluetooth.BluetoothAdapter.html
index f430f52..cb152f9 100644
--- a/docs/html/sdk/api_diff/16/changes/android.bluetooth.BluetoothAdapter.html
+++ b/docs/html/sdk/api_diff/16/changes/android.bluetooth.BluetoothAdapter.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.AsyncTaskLoader.html b/docs/html/sdk/api_diff/16/changes/android.content.AsyncTaskLoader.html
index 842a312..b153537 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.AsyncTaskLoader.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.AsyncTaskLoader.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ClipData.Item.html b/docs/html/sdk/api_diff/16/changes/android.content.ClipData.Item.html
index f506745..38c37b4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ClipData.Item.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ClipData.Item.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ClipData.html b/docs/html/sdk/api_diff/16/changes/android.content.ClipData.html
index 59c56d2..2f60ec4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ClipData.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ClipData.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ClipDescription.html b/docs/html/sdk/api_diff/16/changes/android.content.ClipDescription.html
index 528513d..dc32779 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ClipDescription.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ClipDescription.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ComponentCallbacks2.html b/docs/html/sdk/api_diff/16/changes/android.content.ComponentCallbacks2.html
index d446190..061fa82 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ComponentCallbacks2.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ComponentCallbacks2.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ContentProvider.html b/docs/html/sdk/api_diff/16/changes/android.content.ContentProvider.html
index 30a4c30..44e061b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ContentProvider.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ContentProvider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ContentProviderClient.html b/docs/html/sdk/api_diff/16/changes/android.content.ContentProviderClient.html
index 48426c90..a70ba55 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ContentProviderClient.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ContentProviderClient.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ContentResolver.html b/docs/html/sdk/api_diff/16/changes/android.content.ContentResolver.html
index 0d1fb1c..773aa64 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ContentResolver.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ContentResolver.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.Context.html b/docs/html/sdk/api_diff/16/changes/android.content.Context.html
index 0134a11..8a07fda 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.Context.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.Context.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.ContextWrapper.html b/docs/html/sdk/api_diff/16/changes/android.content.ContextWrapper.html
index aea7ed4..4a856e4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.ContextWrapper.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.ContextWrapper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.Intent.html b/docs/html/sdk/api_diff/16/changes/android.content.Intent.html
index ce2f2e8..05391d4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.Intent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.Intent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -155,13 +155,6 @@
 </TR>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
-  <A NAME="android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS"></A>
-  <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/Intent.html#FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS" target="_top"><code>FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS</code></A></nobr>
-  </TD>
-  <TD>&nbsp;</TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
-  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="android.content.Intent.FLAG_RECEIVER_FOREGROUND"></A>
   <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/Intent.html#FLAG_RECEIVER_FOREGROUND" target="_top"><code>FLAG_RECEIVER_FOREGROUND</code></A></nobr>
   </TD>
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.Loader.html b/docs/html/sdk/api_diff/16/changes/android.content.Loader.html
index 9a16b88..1fdb042 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.Loader.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.Loader.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/16/changes/android.content.pm.ActivityInfo.html
index 487a129..a2db676 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.pm.ActivityInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.pm.ActivityInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageInfo.html b/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageInfo.html
index 8c5ae8d..408e4c2 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageManager.html
index 0231400..65c5f21 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.pm.PackageManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.pm.PermissionInfo.html b/docs/html/sdk/api_diff/16/changes/android.content.pm.PermissionInfo.html
index de8898e..6000877 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.pm.PermissionInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.pm.PermissionInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.pm.ServiceInfo.html b/docs/html/sdk/api_diff/16/changes/android.content.pm.ServiceInfo.html
index 19ff184..07018f0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.pm.ServiceInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.pm.ServiceInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.res.Configuration.html b/docs/html/sdk/api_diff/16/changes/android.content.res.Configuration.html
index 635bf0f..00f3f75a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.res.Configuration.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.res.Configuration.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.content.res.Resources.html b/docs/html/sdk/api_diff/16/changes/android.content.res.Resources.html
index 2a82c03..dca61d8 100644
--- a/docs/html/sdk/api_diff/16/changes/android.content.res.Resources.html
+++ b/docs/html/sdk/api_diff/16/changes/android.content.res.Resources.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.AbstractCursor.html b/docs/html/sdk/api_diff/16/changes/android.database.AbstractCursor.html
index 8ef30ef..7a42022 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.AbstractCursor.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.AbstractCursor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.ContentObservable.html b/docs/html/sdk/api_diff/16/changes/android.database.ContentObservable.html
index 0d53bbf..ec458e4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.ContentObservable.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.ContentObservable.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.ContentObserver.html b/docs/html/sdk/api_diff/16/changes/android.database.ContentObserver.html
index 8402333..4f376b4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.ContentObserver.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.ContentObserver.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.Cursor.html b/docs/html/sdk/api_diff/16/changes/android.database.Cursor.html
index 0d4873e..024e8d0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.Cursor.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.Cursor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.CursorWindow.html b/docs/html/sdk/api_diff/16/changes/android.database.CursorWindow.html
index 6a31252..c42f140 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.CursorWindow.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.CursorWindow.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.SQLException.html b/docs/html/sdk/api_diff/16/changes/android.database.SQLException.html
index e075b44..1f6e1c1 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.SQLException.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.SQLException.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteClosable.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteClosable.html
index adebae2..cb1552d 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteClosable.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteClosable.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteDatabase.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteDatabase.html
index d1f82f5..12ad842 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteDatabase.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteDatabase.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteException.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteException.html
index 5c71efd..d6e4ebc 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteException.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteException.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteOpenHelper.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteOpenHelper.html
index 2ad2b7c..08a21fe 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteOpenHelper.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteOpenHelper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteProgram.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteProgram.html
index 6e65aeb..854d9fc 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteProgram.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteProgram.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQuery.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQuery.html
index 39174af..eeec07c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQuery.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQuery.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQueryBuilder.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQueryBuilder.html
index a96030b..9863ac3 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQueryBuilder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteQueryBuilder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteStatement.html b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteStatement.html
index a09a341..3df6e69 100644
--- a/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteStatement.html
+++ b/docs/html/sdk/api_diff/16/changes/android.database.sqlite.SQLiteStatement.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmManagerClient.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmManagerClient.html
index 266ff09..5eee746 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmManagerClient.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmManagerClient.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Action.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Action.html
index cf6f50d..2aaf764 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Action.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Action.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.DrmObjectType.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.DrmObjectType.html
index 87ff8da..122e3ae 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.DrmObjectType.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.DrmObjectType.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Playback.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Playback.html
index 594c4c0..f2038d9 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Playback.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.Playback.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.RightsStatus.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.RightsStatus.html
index c0525ab..37b04a8 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.RightsStatus.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.RightsStatus.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.html
index 75686cc..7039935 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmStore.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.drm.DrmSupportInfo.html b/docs/html/sdk/api_diff/16/changes/android.drm.DrmSupportInfo.html
index a62b31de..ab22f87 100644
--- a/docs/html/sdk/api_diff/16/changes/android.drm.DrmSupportInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.drm.DrmSupportInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.AvoidXfermode.html b/docs/html/sdk/api_diff/16/changes/android.graphics.AvoidXfermode.html
index b6c4f59..e9d0ebe 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.AvoidXfermode.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.AvoidXfermode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.Camera.html b/docs/html/sdk/api_diff/16/changes/android.graphics.Camera.html
index 27b6d32..f75d71b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.Camera.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.Camera.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.Canvas.html b/docs/html/sdk/api_diff/16/changes/android.graphics.Canvas.html
index d94562a..f025bc0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.Canvas.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.Canvas.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.Paint.html b/docs/html/sdk/api_diff/16/changes/android.graphics.Paint.html
index f5d5f79..bad0f84 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.Paint.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.Paint.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.PixelFormat.html b/docs/html/sdk/api_diff/16/changes/android.graphics.PixelFormat.html
index d6f4453..ea2342b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.PixelFormat.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.PixelFormat.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.PixelXorXfermode.html b/docs/html/sdk/api_diff/16/changes/android.graphics.PixelXorXfermode.html
index c56d90e..147d373 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.PixelXorXfermode.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.PixelXorXfermode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.SurfaceTexture.html b/docs/html/sdk/api_diff/16/changes/android.graphics.SurfaceTexture.html
index 66749dee..ecd2e9f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.SurfaceTexture.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.SurfaceTexture.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.graphics.drawable.GradientDrawable.html b/docs/html/sdk/api_diff/16/changes/android.graphics.drawable.GradientDrawable.html
index 4e0a4ba..387d2d9 100644
--- a/docs/html/sdk/api_diff/16/changes/android.graphics.drawable.GradientDrawable.html
+++ b/docs/html/sdk/api_diff/16/changes/android.graphics.drawable.GradientDrawable.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.hardware.Camera.html b/docs/html/sdk/api_diff/16/changes/android.hardware.Camera.html
index 9e62312..5329266 100644
--- a/docs/html/sdk/api_diff/16/changes/android.hardware.Camera.html
+++ b/docs/html/sdk/api_diff/16/changes/android.hardware.Camera.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.hardware.SensorManager.html b/docs/html/sdk/api_diff/16/changes/android.hardware.SensorManager.html
index c5733325..6b8316c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.hardware.SensorManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.hardware.SensorManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.AudioManager.html b/docs/html/sdk/api_diff/16/changes/android.media.AudioManager.html
index 7a8f61f..4ad8ede 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.AudioManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.AudioManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.AudioRecord.html b/docs/html/sdk/api_diff/16/changes/android.media.AudioRecord.html
index 567ae50..00502f1 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.AudioRecord.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.AudioRecord.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.MediaPlayer.html b/docs/html/sdk/api_diff/16/changes/android.media.MediaPlayer.html
index a5ceaad..602686e 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.MediaPlayer.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.MediaPlayer.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.AudioEncoder.html b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.AudioEncoder.html
index 01b0dfb..4672d3a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.AudioEncoder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.AudioEncoder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.OutputFormat.html b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.OutputFormat.html
index 6f529c8..cc155eb 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.OutputFormat.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.OutputFormat.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.html b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.html
index 41fa5179..ab168ed 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.MediaRecorder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.ToneGenerator.html b/docs/html/sdk/api_diff/16/changes/android.media.ToneGenerator.html
index 4b67fb3..db2c2436 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.ToneGenerator.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.ToneGenerator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.media.audiofx.Visualizer.html b/docs/html/sdk/api_diff/16/changes/android.media.audiofx.Visualizer.html
index ce70faa..2d359ea 100644
--- a/docs/html/sdk/api_diff/16/changes/android.media.audiofx.Visualizer.html
+++ b/docs/html/sdk/api_diff/16/changes/android.media.audiofx.Visualizer.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.net.ConnectivityManager.html b/docs/html/sdk/api_diff/16/changes/android.net.ConnectivityManager.html
index af5f08b..151f58a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.net.ConnectivityManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.net.ConnectivityManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.net.SSLCertificateSocketFactory.html b/docs/html/sdk/api_diff/16/changes/android.net.SSLCertificateSocketFactory.html
index 4f215ac..69cf35d 100644
--- a/docs/html/sdk/api_diff/16/changes/android.net.SSLCertificateSocketFactory.html
+++ b/docs/html/sdk/api_diff/16/changes/android.net.SSLCertificateSocketFactory.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.net.Uri.html b/docs/html/sdk/api_diff/16/changes/android.net.Uri.html
index 0573fe6..c8d747b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.net.Uri.html
+++ b/docs/html/sdk/api_diff/16/changes/android.net.Uri.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.net.wifi.p2p.WifiP2pManager.html b/docs/html/sdk/api_diff/16/changes/android.net.wifi.p2p.WifiP2pManager.html
index 86520bc..1605831 100644
--- a/docs/html/sdk/api_diff/16/changes/android.net.wifi.p2p.WifiP2pManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.net.wifi.p2p.WifiP2pManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.nfc.FormatException.html b/docs/html/sdk/api_diff/16/changes/android.nfc.FormatException.html
index ec65609..2d6b396 100644
--- a/docs/html/sdk/api_diff/16/changes/android.nfc.FormatException.html
+++ b/docs/html/sdk/api_diff/16/changes/android.nfc.FormatException.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.nfc.NdefMessage.html b/docs/html/sdk/api_diff/16/changes/android.nfc.NdefMessage.html
index 4c9d9d6..9a8db58 100644
--- a/docs/html/sdk/api_diff/16/changes/android.nfc.NdefMessage.html
+++ b/docs/html/sdk/api_diff/16/changes/android.nfc.NdefMessage.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.nfc.NdefRecord.html b/docs/html/sdk/api_diff/16/changes/android.nfc.NdefRecord.html
index a5b159b..0eab428 100644
--- a/docs/html/sdk/api_diff/16/changes/android.nfc.NdefRecord.html
+++ b/docs/html/sdk/api_diff/16/changes/android.nfc.NdefRecord.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.nfc.NfcAdapter.html b/docs/html/sdk/api_diff/16/changes/android.nfc.NfcAdapter.html
index 042a0dd..4d22a1a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.nfc.NfcAdapter.html
+++ b/docs/html/sdk/api_diff/16/changes/android.nfc.NfcAdapter.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.nfc.tech.IsoDep.html b/docs/html/sdk/api_diff/16/changes/android.nfc.tech.IsoDep.html
index 9663328..b6a9cf6 100644
--- a/docs/html/sdk/api_diff/16/changes/android.nfc.tech.IsoDep.html
+++ b/docs/html/sdk/api_diff/16/changes/android.nfc.tech.IsoDep.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/16/changes/android.os.Build.VERSION_CODES.html
index 516985e..422d0c1 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.Build.VERSION_CODES.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.Build.VERSION_CODES.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.ParcelFileDescriptor.html b/docs/html/sdk/api_diff/16/changes/android.os.ParcelFileDescriptor.html
index a73cc14..dec148b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.ParcelFileDescriptor.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.ParcelFileDescriptor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.Process.html b/docs/html/sdk/api_diff/16/changes/android.os.Process.html
index 1ed46fd..7a7c4d5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.Process.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.Process.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.StrictMode.VmPolicy.Builder.html b/docs/html/sdk/api_diff/16/changes/android.os.StrictMode.VmPolicy.Builder.html
index 04305f8..c5c332d 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.StrictMode.VmPolicy.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.StrictMode.VmPolicy.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.TokenWatcher.html b/docs/html/sdk/api_diff/16/changes/android.os.TokenWatcher.html
index 13ceb9f..084af83 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.TokenWatcher.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.TokenWatcher.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.os.Vibrator.html b/docs/html/sdk/api_diff/16/changes/android.os.Vibrator.html
index 9946d85..6b20dac 100644
--- a/docs/html/sdk/api_diff/16/changes/android.os.Vibrator.html
+++ b/docs/html/sdk/api_diff/16/changes/android.os.Vibrator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.AttendeesColumns.html b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.AttendeesColumns.html
index e076397..f1a9577 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.AttendeesColumns.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.AttendeesColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.EventsColumns.html b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.EventsColumns.html
index dbb369a..868f1de 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.EventsColumns.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.EventsColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.RemindersColumns.html b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.RemindersColumns.html
index e55e138..1d9e485 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.RemindersColumns.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.RemindersColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.html b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.html
index 07098f1..172b1ed 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.CalendarContract.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.CommonDataKinds.Phone.html b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.CommonDataKinds.Phone.html
index 477a51c..21d29b8 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.CommonDataKinds.Phone.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.CommonDataKinds.Phone.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.Contacts.html b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.Contacts.html
index 6d9df3f..a0f3ad6 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.Contacts.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.Contacts.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.DataUsageFeedback.html b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.DataUsageFeedback.html
index 0b4380c..e27e55c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.DataUsageFeedback.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.DataUsageFeedback.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.PhoneLookupColumns.html b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.PhoneLookupColumns.html
index 6ffe8ac..086f29a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.PhoneLookupColumns.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.ContactsContract.PhoneLookupColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.MediaStore.MediaColumns.html b/docs/html/sdk/api_diff/16/changes/android.provider.MediaStore.MediaColumns.html
index 3f34460..1e9b8dd 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.MediaStore.MediaColumns.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.MediaStore.MediaColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.Secure.html
index 99884f4..85b97e3 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.Secure.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.Secure.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.System.html b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.System.html
index 74c8eb3..b13218a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.System.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.System.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.html b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.html
index 39342f1..fdd2e82 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.Settings.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.Settings.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.provider.UserDictionary.Words.html b/docs/html/sdk/api_diff/16/changes/android.provider.UserDictionary.Words.html
index 2cc1bc0..048f9e7 100644
--- a/docs/html/sdk/api_diff/16/changes/android.provider.UserDictionary.Words.html
+++ b/docs/html/sdk/api_diff/16/changes/android.provider.UserDictionary.Words.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Allocation.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Allocation.html
index 66c3db9..a63823f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Allocation.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Allocation.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Element.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Element.html
index 41fea88..c2e53fe 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Element.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Element.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.EntryType.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.EntryType.html
index 17292dc..ef49db3 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.EntryType.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.EntryType.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.IndexEntry.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.IndexEntry.html
index 121c272..5d5f307 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.IndexEntry.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.IndexEntry.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.html
index 6736ffd..3f65c2c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.FileA3D.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.Style.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.Style.html
index 3f00425..85bca91 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.Style.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.Style.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.html
index b1c1ae6..b9efb85 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Font.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.AllocationBuilder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.AllocationBuilder.html
index f8ad159..faf6237 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.AllocationBuilder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.AllocationBuilder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Builder.html
index 882a7b0..1ed9a63 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Primitive.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Primitive.html
index 73d31db..dc94449 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Primitive.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.Primitive.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.TriangleMeshBuilder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.TriangleMeshBuilder.html
index 90a7dce..30772e0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.TriangleMeshBuilder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.TriangleMeshBuilder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.html
index 2030ed0..a7d6b19 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Mesh.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.BaseProgramBuilder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.BaseProgramBuilder.html
index 4f0b6e1..f2ece67 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.BaseProgramBuilder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.BaseProgramBuilder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.html
index 9b0718e..cea3097 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Program.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.Builder.html
index bf9c417..b6c50d3 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.html
index 53dd0f8..82f0614 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragment.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode.html
index 8289e9c5..42e4c41 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.EnvMode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.Format.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.Format.html
index 4f8be80..6b0d42a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.Format.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.Format.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.html
index bc9d8e9..866e75e 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.html
index 0073206..043927d 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramFragmentFixedFunction.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.Builder.html
index 4dbb440..7a36129 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.CullMode.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.CullMode.html
index 3175579..135a7bf 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.CullMode.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.CullMode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.html
index cccfc7e..60042f4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramRaster.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramStore.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramStore.html
index 16b2ef3..4e96e4f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramStore.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramStore.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.Builder.html
index 111140d..adfdd1c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.html
index e72f32c..278079f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertex.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Builder.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Builder.html
index edbc528..52bbdf9 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Builder.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Constants.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Constants.html
index 3a9b272..274ae05 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Constants.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.Constants.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.html
index 5dd5e7a..6b1894f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.ProgramVertexFixedFunction.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.RSSurfaceView.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.RSSurfaceView.html
index 55c3b49..7c9d264b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.RSSurfaceView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.RSSurfaceView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.RSTextureView.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.RSTextureView.html
index 3fc1497..b0b87ae 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.RSTextureView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.RSTextureView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.SurfaceConfig.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.SurfaceConfig.html
index da5f05f..e07b1ac 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.SurfaceConfig.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.SurfaceConfig.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.html
index a0ad13e..6cf0f6c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.RenderScriptGL.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Sampler.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Sampler.html
index 8421eb8..1345dae5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Sampler.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Sampler.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.renderscript.Script.html b/docs/html/sdk/api_diff/16/changes/android.renderscript.Script.html
index bf71177..8fc9924 100644
--- a/docs/html/sdk/api_diff/16/changes/android.renderscript.Script.html
+++ b/docs/html/sdk/api_diff/16/changes/android.renderscript.Script.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.security.KeyChain.html b/docs/html/sdk/api_diff/16/changes/android.security.KeyChain.html
index 7514250..92e57b5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.security.KeyChain.html
+++ b/docs/html/sdk/api_diff/16/changes/android.security.KeyChain.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.service.textservice.SpellCheckerService.Session.html b/docs/html/sdk/api_diff/16/changes/android.service.textservice.SpellCheckerService.Session.html
index 6194cf6..c83d21f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.service.textservice.SpellCheckerService.Session.html
+++ b/docs/html/sdk/api_diff/16/changes/android.service.textservice.SpellCheckerService.Session.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.speech.RecognizerIntent.html b/docs/html/sdk/api_diff/16/changes/android.speech.RecognizerIntent.html
index 59ee347..d869c23 100644
--- a/docs/html/sdk/api_diff/16/changes/android.speech.RecognizerIntent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.speech.RecognizerIntent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.test.AssertionFailedError.html b/docs/html/sdk/api_diff/16/changes/android.test.AssertionFailedError.html
index 23d47dd..feba168 100644
--- a/docs/html/sdk/api_diff/16/changes/android.test.AssertionFailedError.html
+++ b/docs/html/sdk/api_diff/16/changes/android.test.AssertionFailedError.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.test.ComparisonFailure.html b/docs/html/sdk/api_diff/16/changes/android.test.ComparisonFailure.html
index 1c9d008..4f9406d 100644
--- a/docs/html/sdk/api_diff/16/changes/android.test.ComparisonFailure.html
+++ b/docs/html/sdk/api_diff/16/changes/android.test.ComparisonFailure.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.test.InstrumentationTestSuite.html b/docs/html/sdk/api_diff/16/changes/android.test.InstrumentationTestSuite.html
index 41d0de8..41f0bc0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.test.InstrumentationTestSuite.html
+++ b/docs/html/sdk/api_diff/16/changes/android.test.InstrumentationTestSuite.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.test.mock.MockContext.html b/docs/html/sdk/api_diff/16/changes/android.test.mock.MockContext.html
index 878bc32..a44c902 100644
--- a/docs/html/sdk/api_diff/16/changes/android.test.mock.MockContext.html
+++ b/docs/html/sdk/api_diff/16/changes/android.test.mock.MockContext.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.text.Html.html b/docs/html/sdk/api_diff/16/changes/android.text.Html.html
index 1d2c46d..a0361cd 100644
--- a/docs/html/sdk/api_diff/16/changes/android.text.Html.html
+++ b/docs/html/sdk/api_diff/16/changes/android.text.Html.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.util.DisplayMetrics.html b/docs/html/sdk/api_diff/16/changes/android.util.DisplayMetrics.html
index c563255..2f93ccf 100644
--- a/docs/html/sdk/api_diff/16/changes/android.util.DisplayMetrics.html
+++ b/docs/html/sdk/api_diff/16/changes/android.util.DisplayMetrics.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ActionMode.html b/docs/html/sdk/api_diff/16/changes/android.view.ActionMode.html
index 4d7dba4..0633827 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ActionMode.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ActionMode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ActionProvider.html b/docs/html/sdk/api_diff/16/changes/android.view.ActionProvider.html
index 295e6f1..9c65f8f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ActionProvider.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ActionProvider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -83,11 +83,39 @@
 </TH>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.view.ActionProvider.isVisible_added()"></A>
+  <nobr><code>boolean</code>&nbsp;<A HREF="../../../../reference/android/view/ActionProvider.html#isVisible()" target="_top"><code>isVisible</code></A>()</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="android.view.ActionProvider.onCreateActionView_added(android.view.MenuItem)"></A>
   <nobr><code>View</code>&nbsp;<A HREF="../../../../reference/android/view/ActionProvider.html#onCreateActionView(android.view.MenuItem)" target="_top"><code>onCreateActionView</code></A>(<code>MenuItem</code>)</nobr>
   </TD>
   <TD>&nbsp;</TD>
 </TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.view.ActionProvider.overridesItemVisibility_added()"></A>
+  <nobr><code>boolean</code>&nbsp;<A HREF="../../../../reference/android/view/ActionProvider.html#overridesItemVisibility()" target="_top"><code>overridesItemVisibility</code></A>()</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.view.ActionProvider.refreshVisibility_added()"></A>
+  <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/view/ActionProvider.html#refreshVisibility()" target="_top"><code>refreshVisibility</code></A>()</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)"></A>
+  <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/view/ActionProvider.html#setVisibilityListener(android.view.ActionProvider.VisibilityListener)" target="_top"><code>setVisibilityListener</code></A>(<code>VisibilityListener</code>)</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
 </TABLE>
 &nbsp;
 <p>
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.Display.html b/docs/html/sdk/api_diff/16/changes/android.view.Display.html
index e1db224..c519edf 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.Display.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.Display.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.Gravity.html b/docs/html/sdk/api_diff/16/changes/android.view.Gravity.html
index c8dfc0b..7e6daea 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.Gravity.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.Gravity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.InputDevice.html b/docs/html/sdk/api_diff/16/changes/android.view.InputDevice.html
index e787591..9515708 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.InputDevice.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.InputDevice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.InputEvent.html b/docs/html/sdk/api_diff/16/changes/android.view.InputEvent.html
index c41ca44..e3b872c 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.InputEvent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.InputEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.KeyCharacterMap.html b/docs/html/sdk/api_diff/16/changes/android.view.KeyCharacterMap.html
index 4e414f3..e18e9b5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.KeyCharacterMap.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.KeyCharacterMap.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/16/changes/android.view.KeyEvent.html
index 9c35b87..bedd73f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.KeyEvent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.KeyEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.TextureView.html b/docs/html/sdk/api_diff/16/changes/android.view.TextureView.html
index 5e835f3..e8fd732 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.TextureView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.TextureView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.View.AccessibilityDelegate.html b/docs/html/sdk/api_diff/16/changes/android.view.View.AccessibilityDelegate.html
index 04a4157..6350eee 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.View.AccessibilityDelegate.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.View.AccessibilityDelegate.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.View.html b/docs/html/sdk/api_diff/16/changes/android.view.View.html
index 8b8bc43..015f638 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.View.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.View.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.HierarchyTraceType.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.HierarchyTraceType.html
index 9098260..e908fb5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.HierarchyTraceType.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.HierarchyTraceType.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.RecyclerTraceType.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.RecyclerTraceType.html
index f25f40f..6fa0d11 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.RecyclerTraceType.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.RecyclerTraceType.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.html
index 6405673..9bc7af1 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewDebug.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewGroup.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewGroup.html
index adf11b4..e30c4b3 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewGroup.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewGroup.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewParent.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewParent.html
index a6b7f00..fc32c23 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewParent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewParent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewPropertyAnimator.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewPropertyAnimator.html
index eb6f3b4..49be2b7 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewPropertyAnimator.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewPropertyAnimator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewStub.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewStub.html
index cc5a4c6..ff1b0fe 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewStub.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewStub.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.ViewTreeObserver.html b/docs/html/sdk/api_diff/16/changes/android.view.ViewTreeObserver.html
index e679ce2..8ba4bab 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.ViewTreeObserver.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.ViewTreeObserver.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityEvent.html b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityEvent.html
index 0a8cfe8..0c51ee4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityEvent.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityNodeInfo.html b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityNodeInfo.html
index 7e10499..7d3e447 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityNodeInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityNodeInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityRecord.html b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityRecord.html
index bf3b7a7..9637ca2 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityRecord.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.accessibility.AccessibilityRecord.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.EditorInfo.html b/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.EditorInfo.html
index 8e15797..bd05573 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.EditorInfo.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.EditorInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.InputMethodManager.html b/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.InputMethodManager.html
index 99da059..c8194cf 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.InputMethodManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.inputmethod.InputMethodManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener.html b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener.html
index e8b3049..0873414 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.html b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.html
index 2828329..32fc681 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSession.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSubtype.html b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSubtype.html
index 1bc66c2..068b5b8 100644
--- a/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSubtype.html
+++ b/docs/html/sdk/api_diff/16/changes/android.view.textservice.SpellCheckerSubtype.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.CookieManager.html b/docs/html/sdk/api_diff/16/changes/android.webkit.CookieManager.html
index 20b9bb3..b740796 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.CookieManager.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.CookieManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.GeolocationPermissions.html b/docs/html/sdk/api_diff/16/changes/android.webkit.GeolocationPermissions.html
index 7859c05..3ffe9a7 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.GeolocationPermissions.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.GeolocationPermissions.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.JsResult.html b/docs/html/sdk/api_diff/16/changes/android.webkit.JsResult.html
index 0023588..8f2577f 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.JsResult.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.JsResult.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.WebIconDatabase.html b/docs/html/sdk/api_diff/16/changes/android.webkit.WebIconDatabase.html
index 4483b47..26024f2 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.WebIconDatabase.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.WebIconDatabase.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/16/changes/android.webkit.WebSettings.html
index 566c7fc..6337887 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.WebSettings.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.WebSettings.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.WebStorage.html b/docs/html/sdk/api_diff/16/changes/android.webkit.WebStorage.html
index 2a62fec..b900c0a 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.WebStorage.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.WebStorage.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.HitTestResult.html b/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.HitTestResult.html
index 31ba76f..f3a25c0 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.HitTestResult.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.HitTestResult.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.html b/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.html
index 0e4a3a0..e009999 100644
--- a/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.webkit.WebView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.AbsSeekBar.html b/docs/html/sdk/api_diff/16/changes/android.widget.AbsSeekBar.html
index 84d76c8..e5ca3d5 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.AbsSeekBar.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.AbsSeekBar.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewAnimator.html b/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewAnimator.html
index 4dc2df5..1b484be 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewAnimator.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewAnimator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewFlipper.html b/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewFlipper.html
index 5f65166..aa2f295 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewFlipper.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.AdapterViewFlipper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.AutoCompleteTextView.html b/docs/html/sdk/api_diff/16/changes/android.widget.AutoCompleteTextView.html
index 8e9bfa7..d32a076 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.AutoCompleteTextView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.AutoCompleteTextView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.CalendarView.html b/docs/html/sdk/api_diff/16/changes/android.widget.CalendarView.html
index 471508c..fd7b0e4 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.CalendarView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.CalendarView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.CheckedTextView.html b/docs/html/sdk/api_diff/16/changes/android.widget.CheckedTextView.html
index 63f1f38..4d257dc 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.CheckedTextView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.CheckedTextView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.FrameLayout.html b/docs/html/sdk/api_diff/16/changes/android.widget.FrameLayout.html
index 285f4c3..2d18399 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.FrameLayout.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.FrameLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.Gallery.html b/docs/html/sdk/api_diff/16/changes/android.widget.Gallery.html
index 1d524e9..bea43e60 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.Gallery.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.Gallery.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.GridLayout.html b/docs/html/sdk/api_diff/16/changes/android.widget.GridLayout.html
index 4d08a2d..70600ae 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.GridLayout.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.GridLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.GridView.html b/docs/html/sdk/api_diff/16/changes/android.widget.GridView.html
index 27af520..31a0a95 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.GridView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.GridView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.ImageView.html b/docs/html/sdk/api_diff/16/changes/android.widget.ImageView.html
index f2928f9..bb505bf 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.ImageView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.ImageView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.LinearLayout.html b/docs/html/sdk/api_diff/16/changes/android.widget.LinearLayout.html
index e0f2670..f7717ec 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.LinearLayout.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.LinearLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.RelativeLayout.html b/docs/html/sdk/api_diff/16/changes/android.widget.RelativeLayout.html
index 4c62dc1..75ce6e6 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.RelativeLayout.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.RelativeLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/16/changes/android.widget.RemoteViews.html
index c29df4b..c05ae10 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.RemoteViews.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.RemoteViews.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -103,6 +103,27 @@
   </TD>
   <TD>&nbsp;</TD>
 </TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)"></A>
+  <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/widget/RemoteViews.html#setTextViewCompoundDrawablesRelative(int, int, int, int, int)" target="_top"><code>setTextViewCompoundDrawablesRelative</code></A>(<code>int,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)"></A>
+  <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/widget/RemoteViews.html#setTextViewTextSize(int, int, float)" target="_top"><code>setTextViewTextSize</code></A>(<code>int,</nobr> int<nobr>,</nobr> float<nobr><nobr></code>)</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)"></A>
+  <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/widget/RemoteViews.html#setViewPadding(int, int, int, int, int)" target="_top"><code>setViewPadding</code></A>(<code>int,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
 </TABLE>
 &nbsp;
 <a NAME="fields"></a>
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.SearchView.html b/docs/html/sdk/api_diff/16/changes/android.widget.SearchView.html
index 194fa0b..0cd0cfb 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.SearchView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.SearchView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.Spinner.html b/docs/html/sdk/api_diff/16/changes/android.widget.Spinner.html
index 8525939..0d571994 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.Spinner.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.Spinner.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.Switch.html b/docs/html/sdk/api_diff/16/changes/android.widget.Switch.html
index e8947d6..6fa62d40 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.Switch.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.Switch.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/android.widget.TextView.html b/docs/html/sdk/api_diff/16/changes/android.widget.TextView.html
index 03dab15..0cb483b 100644
--- a/docs/html/sdk/api_diff/16/changes/android.widget.TextView.html
+++ b/docs/html/sdk/api_diff/16/changes/android.widget.TextView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/changes-summary.html b/docs/html/sdk/api_diff/16/changes/changes-summary.html
index 3edac63..93c9aaa 100644
--- a/docs/html/sdk/api_diff/16/changes/changes-summary.html
+++ b/docs/html/sdk/api_diff/16/changes/changes-summary.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/classes_index_additions.html b/docs/html/sdk/api_diff/16/changes/classes_index_additions.html
index d88c0a1..4cd366a 100644
--- a/docs/html/sdk/api_diff/16/changes/classes_index_additions.html
+++ b/docs/html/sdk/api_diff/16/changes/classes_index_additions.html
@@ -62,6 +62,7 @@
 <p><div style="line-height:1.5em;color:black">
 <A HREF="pkg_android.view.accessibility.html#AccessibilityNodeProvider" class="hiddenlink" target="rightframe"><b>AccessibilityNodeProvider</b></A><br>
 <A HREF="pkg_android.media.audiofx.html#AcousticEchoCanceler" class="hiddenlink" target="rightframe"><b>AcousticEchoCanceler</b></A><br>
+<A HREF="pkg_android.view.html#ActionProvider.VisibilityListener" class="hiddenlink" target="rightframe"><b><i>ActionProvider.VisibilityListener</i></b></A><br>
 <A HREF="pkg_android.app.html#ActivityOptions" class="hiddenlink" target="rightframe"><b>ActivityOptions</b></A><br>
 <A HREF="pkg_android.widget.html#Advanceable" class="hiddenlink" target="rightframe"><b><i>Advanceable</i></b></A><br>
 <A HREF="pkg_android.media.audiofx.html#AutomaticGainControl" class="hiddenlink" target="rightframe"><b>AutomaticGainControl</b></A><br>
@@ -135,6 +136,7 @@
 <A HREF="pkg_android.media.html#MediaRouter.RouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.RouteInfo</b></A><br>
 <A HREF="pkg_android.media.html#MediaRouter.SimpleCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.SimpleCallback</b></A><br>
 <A HREF="pkg_android.media.html#MediaRouter.UserRouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.UserRouteInfo</b></A><br>
+<A HREF="pkg_android.media.html#MediaRouter.VolumeCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.VolumeCallback</b></A><br>
 <A HREF="pkg_android.media.html#MediaSyncEvent" class="hiddenlink" target="rightframe"><b>MediaSyncEvent</b></A><br>
 <A NAME="N"></A>
 <br><font size="+2">N</font>&nbsp;
diff --git a/docs/html/sdk/api_diff/16/changes/classes_index_all.html b/docs/html/sdk/api_diff/16/changes/classes_index_all.html
index 97a4d85..6caf76c 100644
--- a/docs/html/sdk/api_diff/16/changes/classes_index_all.html
+++ b/docs/html/sdk/api_diff/16/changes/classes_index_all.html
@@ -83,6 +83,7 @@
 <A HREF="pkg_android.media.audiofx.html#AcousticEchoCanceler" class="hiddenlink" target="rightframe"><b>AcousticEchoCanceler</b></A><br>
 <A HREF="android.view.ActionMode.html" class="hiddenlink" target="rightframe">ActionMode</A><br>
 <A HREF="android.view.ActionProvider.html" class="hiddenlink" target="rightframe">ActionProvider</A><br>
+<A HREF="pkg_android.view.html#ActionProvider.VisibilityListener" class="hiddenlink" target="rightframe"><b><i>ActionProvider.VisibilityListener</i></b></A><br>
 <A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
 <A HREF="android.content.pm.ActivityInfo.html" class="hiddenlink" target="rightframe">ActivityInfo</A><br>
 <A HREF="android.app.ActivityManager.html" class="hiddenlink" target="rightframe">ActivityManager</A><br>
@@ -520,6 +521,7 @@
 <A HREF="pkg_android.media.html#MediaRouter.RouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.RouteInfo</b></A><br>
 <A HREF="pkg_android.media.html#MediaRouter.SimpleCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.SimpleCallback</b></A><br>
 <A HREF="pkg_android.media.html#MediaRouter.UserRouteInfo" class="hiddenlink" target="rightframe"><b>MediaRouter.UserRouteInfo</b></A><br>
+<A HREF="pkg_android.media.html#MediaRouter.VolumeCallback" class="hiddenlink" target="rightframe"><b>MediaRouter.VolumeCallback</b></A><br>
 <A HREF="android.provider.MediaStore.MediaColumns.html" class="hiddenlink" target="rightframe"><i>MediaStore.MediaColumns</i></A><br>
 <A HREF="pkg_android.media.html#MediaSyncEvent" class="hiddenlink" target="rightframe"><b>MediaSyncEvent</b></A><br>
 <A HREF="android.renderscript.Mesh.html" class="hiddenlink" target="rightframe">Mesh</A><br>
diff --git a/docs/html/sdk/api_diff/16/changes/fields_index_additions.html b/docs/html/sdk/api_diff/16/changes/fields_index_additions.html
index 7ca7ad6..0d93032 100644
--- a/docs/html/sdk/api_diff/16/changes/fields_index_additions.html
+++ b/docs/html/sdk/api_diff/16/changes/fields_index_additions.html
@@ -289,8 +289,6 @@
 </nobr><br>
 <nobr><A HREF="android.content.Intent.html#android.content.Intent.FILL_IN_CLIP_DATA" class="hiddenlink" target="rightframe">FILL_IN_CLIP_DATA</A>
 </nobr><br>
-<nobr><A HREF="android.content.Intent.html#android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS" class="hiddenlink" target="rightframe">FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS</A>
-</nobr><br>
 <nobr><A HREF="android.accessibilityservice.AccessibilityServiceInfo.html#android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS" class="hiddenlink" target="rightframe">FLAG_INCLUDE_NOT_IMPORTANT_VIEWS</A>
 </nobr><br>
 <nobr><A HREF="android.content.pm.ServiceInfo.html#android.content.pm.ServiceInfo.FLAG_ISOLATED_PROCESS" class="hiddenlink" target="rightframe">FLAG_ISOLATED_PROCESS</A>
@@ -570,6 +568,8 @@
 </nobr><br>
 <nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteButtonStyle" class="hiddenlink" target="rightframe">mediaRouteButtonStyle</A>
 </nobr><br>
+<nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteTypes" class="hiddenlink" target="rightframe">mediaRouteTypes</A>
+</nobr><br>
 <nobr><A HREF="android.provider.CalendarContract.RemindersColumns.html#android.provider.CalendarContract.RemindersColumns.METHOD_ALARM" class="hiddenlink" target="rightframe">METHOD_ALARM</A>
 </nobr><br>
 <nobr><A HREF="android.content.ClipDescription.html#android.content.ClipDescription.MIMETYPE_TEXT_HTML" class="hiddenlink" target="rightframe">MIMETYPE_TEXT_HTML</A>
diff --git a/docs/html/sdk/api_diff/16/changes/fields_index_all.html b/docs/html/sdk/api_diff/16/changes/fields_index_all.html
index e7dea5d..2eee5e3 100644
--- a/docs/html/sdk/api_diff/16/changes/fields_index_all.html
+++ b/docs/html/sdk/api_diff/16/changes/fields_index_all.html
@@ -323,8 +323,6 @@
 </nobr><br>
 <nobr><A HREF="android.content.Intent.html#android.content.Intent.FILL_IN_CLIP_DATA" class="hiddenlink" target="rightframe">FILL_IN_CLIP_DATA</A>
 </nobr><br>
-<nobr><A HREF="android.content.Intent.html#android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS" class="hiddenlink" target="rightframe">FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS</A>
-</nobr><br>
 <nobr><A HREF="android.app.Notification.html#android.app.Notification.FLAG_HIGH_PRIORITY" class="hiddenlink" target="rightframe">FLAG_HIGH_PRIORITY</A>
 </nobr><br>
 <nobr><A HREF="android.accessibilityservice.AccessibilityServiceInfo.html#android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS" class="hiddenlink" target="rightframe">FLAG_INCLUDE_NOT_IMPORTANT_VIEWS</A>
@@ -634,6 +632,8 @@
 </nobr><br>
 <nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteButtonStyle" class="hiddenlink" target="rightframe">mediaRouteButtonStyle</A>
 </nobr><br>
+<nobr><A HREF="android.R.attr.html#android.R.attr.mediaRouteTypes" class="hiddenlink" target="rightframe">mediaRouteTypes</A>
+</nobr><br>
 <nobr><A HREF="android.provider.CalendarContract.RemindersColumns.html#android.provider.CalendarContract.RemindersColumns.METHOD_ALARM" class="hiddenlink" target="rightframe">METHOD_ALARM</A>
 </nobr><br>
 <nobr><A HREF="android.content.ClipDescription.html#android.content.ClipDescription.MIMETYPE_TEXT_HTML" class="hiddenlink" target="rightframe">MIMETYPE_TEXT_HTML</A>
diff --git a/docs/html/sdk/api_diff/16/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/16/changes/jdiff_statistics.html
index 090eb6e..f0ddde1 100644
--- a/docs/html/sdk/api_diff/16/changes/jdiff_statistics.html
+++ b/docs/html/sdk/api_diff/16/changes/jdiff_statistics.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -96,10 +96,10 @@
 </TR>
 <TR>
   <TD>Classes and <i>Interfaces</i></TD>
-  <TD ALIGN="right">55</TD>
+  <TD ALIGN="right">57</TD>
   <TD ALIGN="right">211</TD>
   <TD ALIGN="right">0</TD>
-  <TD ALIGN="right">266</TD>
+  <TD ALIGN="right">268</TD>
 </TR>
 <TR>
   <TD>Constructors</TD>
@@ -110,10 +110,10 @@
 </TR>
 <TR>
   <TD>Methods</TD>
-  <TD ALIGN="right">374</TD>
+  <TD ALIGN="right">381</TD>
   <TD ALIGN="right">151</TD>
   <TD ALIGN="right">20</TD>
-  <TD ALIGN="right">545</TD>
+  <TD ALIGN="right">552</TD>
 </TR>
 <TR>
   <TD>Fields</TD>
@@ -124,10 +124,10 @@
 </TR>
 <TR>
   <TD style="background-color:#FAFAFA"><b>Total</b></TD>
-  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>616</strong></TD>
+  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>625</strong></TD>
   <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>469</strong></TD>
   <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>28</strong></TD>
-  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>1113</strong></TD>
+  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>1122</strong></TD>
 </TR>
 </TABLE>
 <br>
@@ -143,7 +143,7 @@
   <TD><A HREF="pkg_android.accessibilityservice.html">android.accessibilityservice</A></TD>
 </TR>
 <TR>
-  <TD ALIGN="center">22</TD>
+  <TD ALIGN="center">23</TD>
   <TD><A HREF="pkg_android.media.html">android.media</A></TD>
 </TR>
 <TR>
@@ -199,12 +199,12 @@
   <TD><A HREF="pkg_android.database.html">android.database</A></TD>
 </TR>
 <TR>
-  <TD ALIGN="center">3</TD>
-  <TD><A HREF="pkg_android.os.html">android.os</A></TD>
+  <TD ALIGN="center">4</TD>
+  <TD><A HREF="pkg_android.view.html">android.view</A></TD>
 </TR>
 <TR>
   <TD ALIGN="center">3</TD>
-  <TD><A HREF="pkg_android.view.html">android.view</A></TD>
+  <TD><A HREF="pkg_android.os.html">android.os</A></TD>
 </TR>
 <TR>
   <TD ALIGN="center">3</TD>
@@ -284,11 +284,11 @@
 </TR>
 <TR>
   <TD ALIGN="center">&lt;1</TD>
-  <TD><A HREF="pkg_android.view.inputmethod.html">android.view.inputmethod</A></TD>
+  <TD><A HREF="pkg_android.html">android</A></TD>
 </TR>
 <TR>
   <TD ALIGN="center">&lt;1</TD>
-  <TD><A HREF="pkg_android.html">android</A></TD>
+  <TD><A HREF="pkg_android.view.inputmethod.html">android.view.inputmethod</A></TD>
 </TR>
 <TR>
   <TD ALIGN="center">&lt;1</TD>
@@ -450,6 +450,11 @@
 junit.framework.ComparisonFailure</A></TD>
 </TR>
 <TR>
+  <TD ALIGN="center">46</TD>
+  <TD><A HREF="android.view.ActionProvider.html">
+android.view.ActionProvider</A></TD>
+</TR>
+<TR>
   <TD ALIGN="center">45</TD>
   <TD><A HREF="android.renderscript.Program.html">
 android.renderscript.Program</A></TD>
@@ -510,11 +515,6 @@
 android.widget.Spinner</A></TD>
 </TR>
 <TR>
-  <TD ALIGN="center">27</TD>
-  <TD><A HREF="android.view.ActionProvider.html">
-android.view.ActionProvider</A></TD>
-</TR>
-<TR>
   <TD ALIGN="center">26</TD>
   <TD><A HREF="android.net.wifi.p2p.WifiP2pManager.html">
 android.net.wifi.p2p.WifiP2pManager</A></TD>
@@ -966,6 +966,11 @@
 </TR>
 <TR>
   <TD ALIGN="center">5</TD>
+  <TD><A HREF="android.widget.RemoteViews.html">
+android.widget.RemoteViews</A></TD>
+</TR>
+<TR>
+  <TD ALIGN="center">5</TD>
   <TD><A HREF="junit.runner.BaseTestRunner.html">
 junit.runner.BaseTestRunner</A></TD>
 </TR>
@@ -1151,11 +1156,6 @@
 </TR>
 <TR>
   <TD ALIGN="center">2</TD>
-  <TD><A HREF="android.widget.RemoteViews.html">
-android.widget.RemoteViews</A></TD>
-</TR>
-<TR>
-  <TD ALIGN="center">2</TD>
   <TD><A HREF="android.app.ActivityManager.RunningAppProcessInfo.html">
 android.app.ActivityManager.RunningAppProcessInfo</A></TD>
 </TR>
@@ -1176,11 +1176,6 @@
 </TR>
 <TR>
   <TD ALIGN="center">1</TD>
-  <TD><A HREF="android.content.Intent.html">
-android.content.Intent</A></TD>
-</TR>
-<TR>
-  <TD ALIGN="center">1</TD>
   <TD><A HREF="android.webkit.WebSettings.html">
 android.webkit.WebSettings</A></TD>
 </TR>
@@ -1211,6 +1206,11 @@
 </TR>
 <TR>
   <TD ALIGN="center">1</TD>
+  <TD><A HREF="android.content.Intent.html">
+android.content.Intent</A></TD>
+</TR>
+<TR>
+  <TD ALIGN="center">1</TD>
   <TD><A HREF="android.widget.LinearLayout.html">
 android.widget.LinearLayout</A></TD>
 </TR>
diff --git a/docs/html/sdk/api_diff/16/changes/junit.framework.Assert.html b/docs/html/sdk/api_diff/16/changes/junit.framework.Assert.html
index 1ccd326..0d5b2cb 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.framework.Assert.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.framework.Assert.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/junit.framework.AssertionFailedError.html b/docs/html/sdk/api_diff/16/changes/junit.framework.AssertionFailedError.html
index cda8b99..8cc284c6 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.framework.AssertionFailedError.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.framework.AssertionFailedError.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/junit.framework.ComparisonFailure.html b/docs/html/sdk/api_diff/16/changes/junit.framework.ComparisonFailure.html
index f8f57bd..afdcc5f 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.framework.ComparisonFailure.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.framework.ComparisonFailure.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/junit.framework.TestResult.html b/docs/html/sdk/api_diff/16/changes/junit.framework.TestResult.html
index 6523319..ada98fd 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.framework.TestResult.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.framework.TestResult.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/junit.framework.TestSuite.html b/docs/html/sdk/api_diff/16/changes/junit.framework.TestSuite.html
index 10e9b56..fd9a0ca 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.framework.TestSuite.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.framework.TestSuite.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/junit.runner.BaseTestRunner.html b/docs/html/sdk/api_diff/16/changes/junit.runner.BaseTestRunner.html
index fc7da24..64880bc 100644
--- a/docs/html/sdk/api_diff/16/changes/junit.runner.BaseTestRunner.html
+++ b/docs/html/sdk/api_diff/16/changes/junit.runner.BaseTestRunner.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/methods_index_additions.html b/docs/html/sdk/api_diff/16/changes/methods_index_additions.html
index 6c34ae3..3264969 100644
--- a/docs/html/sdk/api_diff/16/changes/methods_index_additions.html
+++ b/docs/html/sdk/api_diff/16/changes/methods_index_additions.html
@@ -724,6 +724,8 @@
 (<code>int</code>)</A></nobr><br>
 <nobr><A HREF="android.view.InputDevice.html#android.view.InputDevice.isVirtual_added()" class="hiddenlink" target="rightframe"><b>isVirtual</b>
 ()</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.isVisible_added()" class="hiddenlink" target="rightframe"><b>isVisible</b>
+()</A></nobr><br>
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.isVisibleToUser_added()" class="hiddenlink" target="rightframe"><b>isVisibleToUser</b>
 ()</A></nobr><br>
 <nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.isWriteAheadLoggingEnabled_added()" class="hiddenlink" target="rightframe"><b>isWriteAheadLoggingEnabled</b>
@@ -866,6 +868,8 @@
 (<code>int</code>)</A></nobr><br>
 <nobr><A HREF="android.view.View.html#android.view.View.onWindowSystemUiVisibilityChanged_added(int)" class="hiddenlink" target="rightframe"><b>onWindowSystemUiVisibilityChanged</b>
 (<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.overridesItemVisibility_added()" class="hiddenlink" target="rightframe"><b>overridesItemVisibility</b>
+()</A></nobr><br>
 <A NAME="P"></A>
 <br><font size="+2">P</font>&nbsp;
 <a href="#A"><font size="-2">A</font></a> 
@@ -979,6 +983,8 @@
 (<code>String, String[], CancellationSignal</code>)</A></nobr><br>
 <nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.rawQueryWithFactory_added(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)" class="hiddenlink" target="rightframe"><b>rawQueryWithFactory</b>
 (<code>CursorFactory, String, String[], String, CancellationSignal</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.refreshVisibility_added()" class="hiddenlink" target="rightframe"><b>refreshVisibility</b>
+()</A></nobr><br>
 <nobr><A HREF="android.content.Loader.html#android.content.Loader.registerOnLoadCanceledListener_added(android.content.Loader.OnLoadCanceledListener<D>)" class="hiddenlink" target="rightframe"><b>registerOnLoadCanceledListener</b>
 (<code>OnLoadCanceledListener&lt;D&gt;</code>)</A></nobr><br>
 <nobr><A HREF="android.drm.DrmManagerClient.html#android.drm.DrmManagerClient.release_added()" class="hiddenlink" target="rightframe"><b>release</b>
@@ -1139,6 +1145,10 @@
 (<code>int</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawables_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawables</b>
 (<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawablesRelative</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)" class="hiddenlink" target="rightframe"><b>setTextViewTextSize</b>
+(<code>int, int, float</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbDrawable_added(android.graphics.drawable.Drawable)" class="hiddenlink" target="rightframe"><b>setThumbDrawable</b>
 (<code>Drawable</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbResource_added(int)" class="hiddenlink" target="rightframe"><b>setThumbResource</b>
@@ -1163,6 +1173,10 @@
 (<code>int, FieldPacker, Element, int[]</code>)</A></nobr><br>
 <nobr><A HREF="android.media.MediaPlayer.html#android.media.MediaPlayer.setVideoScalingMode_added(int)" class="hiddenlink" target="rightframe"><b>setVideoScalingMode</b>
 (<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setViewPadding</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)" class="hiddenlink" target="rightframe"><b>setVisibilityListener</b>
+(<code>VisibilityListener</code>)</A></nobr><br>
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.setVisibleToUser_added(boolean)" class="hiddenlink" target="rightframe"><b>setVisibleToUser</b>
 (<code>boolean</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.CalendarView.html#android.widget.CalendarView.setWeekDayTextAppearance_added(int)" class="hiddenlink" target="rightframe"><b>setWeekDayTextAppearance</b>
diff --git a/docs/html/sdk/api_diff/16/changes/methods_index_all.html b/docs/html/sdk/api_diff/16/changes/methods_index_all.html
index 8c91302..628f0b7 100644
--- a/docs/html/sdk/api_diff/16/changes/methods_index_all.html
+++ b/docs/html/sdk/api_diff/16/changes/methods_index_all.html
@@ -1009,6 +1009,8 @@
 (<code>int</code>)</A></nobr><br>
 <nobr><A HREF="android.view.InputDevice.html#android.view.InputDevice.isVirtual_added()" class="hiddenlink" target="rightframe"><b>isVirtual</b>
 ()</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.isVisible_added()" class="hiddenlink" target="rightframe"><b>isVisible</b>
+()</A></nobr><br>
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.isVisibleToUser_added()" class="hiddenlink" target="rightframe"><b>isVisibleToUser</b>
 ()</A></nobr><br>
 <nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.isWriteAheadLoggingEnabled_added()" class="hiddenlink" target="rightframe"><b>isWriteAheadLoggingEnabled</b>
@@ -1192,6 +1194,8 @@
 (<code>SurfaceTexture</code>)</A></nobr><br>
 <nobr><A HREF="android.view.View.html#android.view.View.onWindowSystemUiVisibilityChanged_added(int)" class="hiddenlink" target="rightframe"><b>onWindowSystemUiVisibilityChanged</b>
 (<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.overridesItemVisibility_added()" class="hiddenlink" target="rightframe"><b>overridesItemVisibility</b>
+()</A></nobr><br>
 <A NAME="P"></A>
 <br><font size="+2">P</font>&nbsp;
 <a href="#A"><font size="-2">A</font></a> 
@@ -1318,6 +1322,8 @@
 (<code>String, String[], CancellationSignal</code>)</A></nobr><br>
 <nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.rawQueryWithFactory_added(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)" class="hiddenlink" target="rightframe"><b>rawQueryWithFactory</b>
 (<code>CursorFactory, String, String[], String, CancellationSignal</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.refreshVisibility_added()" class="hiddenlink" target="rightframe"><b>refreshVisibility</b>
+()</A></nobr><br>
 <nobr><A HREF="android.content.Loader.html#android.content.Loader.registerOnLoadCanceledListener_added(android.content.Loader.OnLoadCanceledListener<D>)" class="hiddenlink" target="rightframe"><b>registerOnLoadCanceledListener</b>
 (<code>OnLoadCanceledListener&lt;D&gt;</code>)</A></nobr><br>
 <nobr><A HREF="android.drm.DrmManagerClient.html#android.drm.DrmManagerClient.release_added()" class="hiddenlink" target="rightframe"><b>release</b>
@@ -1576,6 +1582,10 @@
 (<code>boolean</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawables_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawables</b>
 (<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setTextViewCompoundDrawablesRelative</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)" class="hiddenlink" target="rightframe"><b>setTextViewTextSize</b>
+(<code>int, int, float</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbDrawable_added(android.graphics.drawable.Drawable)" class="hiddenlink" target="rightframe"><b>setThumbDrawable</b>
 (<code>Drawable</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.Switch.html#android.widget.Switch.setThumbResource_added(int)" class="hiddenlink" target="rightframe"><b>setThumbResource</b>
@@ -1604,6 +1614,10 @@
 (<code>int, int</code>)</A></nobr><br>
 <nobr><A HREF="android.media.MediaPlayer.html#android.media.MediaPlayer.setVideoScalingMode_added(int)" class="hiddenlink" target="rightframe"><b>setVideoScalingMode</b>
 (<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.widget.RemoteViews.html#android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)" class="hiddenlink" target="rightframe"><b>setViewPadding</b>
+(<code>int, int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.view.ActionProvider.html#android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)" class="hiddenlink" target="rightframe"><b>setVisibilityListener</b>
+(<code>VisibilityListener</code>)</A></nobr><br>
 <nobr><A HREF="android.view.accessibility.AccessibilityNodeInfo.html#android.view.accessibility.AccessibilityNodeInfo.setVisibleToUser_added(boolean)" class="hiddenlink" target="rightframe"><b>setVisibleToUser</b>
 (<code>boolean</code>)</A></nobr><br>
 <nobr><A HREF="android.widget.CalendarView.html#android.widget.CalendarView.setWeekDayTextAppearance_added(int)" class="hiddenlink" target="rightframe"><b>setWeekDayTextAppearance</b>
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.accessibilityservice.html b/docs/html/sdk/api_diff/16/changes/pkg_android.accessibilityservice.html
index 29a51cf..e348264 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.accessibilityservice.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.accessibilityservice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.animation.html b/docs/html/sdk/api_diff/16/changes/pkg_android.animation.html
index b678d70..148635b 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.animation.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.animation.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.app.html b/docs/html/sdk/api_diff/16/changes/pkg_android.app.html
index a9bb343..1eaef10 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.app.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.app.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.appwidget.html b/docs/html/sdk/api_diff/16/changes/pkg_android.appwidget.html
index 59cf0eb..1495d4b 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.appwidget.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.appwidget.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.bluetooth.html b/docs/html/sdk/api_diff/16/changes/pkg_android.bluetooth.html
index 6f66306..f408836 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.bluetooth.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.bluetooth.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.content.html b/docs/html/sdk/api_diff/16/changes/pkg_android.content.html
index 3a7cfe6..cb45c96 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.content.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.content.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/16/changes/pkg_android.content.pm.html
index d926e49..7f80041 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.content.pm.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.content.pm.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.content.res.html b/docs/html/sdk/api_diff/16/changes/pkg_android.content.res.html
index e326722..b2dde4d 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.content.res.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.content.res.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.database.html b/docs/html/sdk/api_diff/16/changes/pkg_android.database.html
index 25f888c..43029e5 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.database.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.database.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.database.sqlite.html b/docs/html/sdk/api_diff/16/changes/pkg_android.database.sqlite.html
index 9566e4f..4c47f61 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.database.sqlite.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.database.sqlite.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.drm.html b/docs/html/sdk/api_diff/16/changes/pkg_android.drm.html
index a8e3f5b..9973797 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.drm.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.drm.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.drawable.html b/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.drawable.html
index 33823cf..e4f0911 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.drawable.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.drawable.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.html
index a43b0ce..3b8d71b 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.graphics.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/16/changes/pkg_android.hardware.html
index bc9dcd3..fb6b102 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.hardware.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.hardware.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.html b/docs/html/sdk/api_diff/16/changes/pkg_android.html
index 5c6d097..19b3c01 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.media.audiofx.html b/docs/html/sdk/api_diff/16/changes/pkg_android.media.audiofx.html
index 1cddd6d..757acd1 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.media.audiofx.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.media.audiofx.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.media.html b/docs/html/sdk/api_diff/16/changes/pkg_android.media.html
index 9d4b42a..5083802 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.media.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.media.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -235,6 +235,13 @@
 </TR>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="MediaRouter.VolumeCallback"></A>
+  <nobr><A HREF="../../../../reference/android/media/MediaRouter.VolumeCallback.html" target="_top"><code>MediaRouter.VolumeCallback</code></A></nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="MediaSyncEvent"></A>
   <nobr><A HREF="../../../../reference/android/media/MediaSyncEvent.html" target="_top"><code>MediaSyncEvent</code></A></nobr>
   </TD>
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.net.html b/docs/html/sdk/api_diff/16/changes/pkg_android.net.html
index 9df67eb..fb9213e 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.net.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.net.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.net.wifi.p2p.html b/docs/html/sdk/api_diff/16/changes/pkg_android.net.wifi.p2p.html
index 0477d8b..e346fed 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.net.wifi.p2p.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.net.wifi.p2p.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.html b/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.html
index b80a460..d6a49d2 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.tech.html b/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.tech.html
index 53eb382..f01ce8c 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.tech.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.nfc.tech.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.os.html b/docs/html/sdk/api_diff/16/changes/pkg_android.os.html
index 93d2f3d..689f8b3 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.os.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.os.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/16/changes/pkg_android.provider.html
index 242a2f7..6a9f620 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.provider.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.provider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.renderscript.html b/docs/html/sdk/api_diff/16/changes/pkg_android.renderscript.html
index ad7a71f..84f8524f 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.renderscript.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.renderscript.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.security.html b/docs/html/sdk/api_diff/16/changes/pkg_android.security.html
index 7a3b458..c3b16dd 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.security.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.security.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.service.textservice.html b/docs/html/sdk/api_diff/16/changes/pkg_android.service.textservice.html
index 773a685..511016d 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.service.textservice.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.service.textservice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.speech.html b/docs/html/sdk/api_diff/16/changes/pkg_android.speech.html
index 26df4e2..990b7b1 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.speech.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.speech.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.test.html b/docs/html/sdk/api_diff/16/changes/pkg_android.test.html
index 71e3841..8d4a6cb 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.test.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.test.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.test.mock.html b/docs/html/sdk/api_diff/16/changes/pkg_android.test.mock.html
index 1d43c38..30be34c 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.test.mock.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.test.mock.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.text.html b/docs/html/sdk/api_diff/16/changes/pkg_android.text.html
index ceaaf3c..378f3b5 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.text.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.text.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.util.html b/docs/html/sdk/api_diff/16/changes/pkg_android.util.html
index 3b12f35..b035341 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.util.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.util.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.view.accessibility.html b/docs/html/sdk/api_diff/16/changes/pkg_android.view.accessibility.html
index 5e68a85..5e2edfe 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.view.accessibility.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.view.accessibility.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.view.html b/docs/html/sdk/api_diff/16/changes/pkg_android.view.html
index 527bed3..85d3c36 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.view.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.view.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -81,6 +81,13 @@
 </TH>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
+  <A NAME="ActionProvider.VisibilityListener"></A>
+  <nobr><A HREF="../../../../reference/android/view/ActionProvider.VisibilityListener.html" target="_top"><code><I>ActionProvider.VisibilityListener</I></code></A></nobr>
+  </TD>
+  <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="Choreographer"></A>
   <nobr><A HREF="../../../../reference/android/view/Choreographer.html" target="_top"><code>Choreographer</code></A></nobr>
   </TD>
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.view.inputmethod.html b/docs/html/sdk/api_diff/16/changes/pkg_android.view.inputmethod.html
index 10e3a61..976a051 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.view.inputmethod.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.view.inputmethod.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.view.textservice.html b/docs/html/sdk/api_diff/16/changes/pkg_android.view.textservice.html
index cc01a3a..c4cac96 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.view.textservice.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.view.textservice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/16/changes/pkg_android.webkit.html
index e00cf29..62fb8ee 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.webkit.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.webkit.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/16/changes/pkg_android.widget.html
index 0736a42..d52b211 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_android.widget.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_android.widget.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_junit.framework.html b/docs/html/sdk/api_diff/16/changes/pkg_junit.framework.html
index 4bd6a2e..a5d6fcc 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_junit.framework.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_junit.framework.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/changes/pkg_junit.runner.html b/docs/html/sdk/api_diff/16/changes/pkg_junit.runner.html
index 96523fb..dcd45ef 100644
--- a/docs/html/sdk/api_diff/16/changes/pkg_junit.runner.html
+++ b/docs/html/sdk/api_diff/16/changes/pkg_junit.runner.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2012.06.26 22:31</td>
+        <td class="diffvalue">2012.07.16 10:58</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/16/missingSinces.txt b/docs/html/sdk/api_diff/16/missingSinces.txt
index 128fb09..9273668 100644
--- a/docs/html/sdk/api_diff/16/missingSinces.txt
+++ b/docs/html/sdk/api_diff/16/missingSinces.txt
@@ -1,5 +1,6 @@
 NO DOC BLOCK: android.view.accessibility.AccessibilityNodeProvider Class
 NO DOC BLOCK: android.media.audiofx.AcousticEchoCanceler Class
+NO DOC BLOCK: android.view.ActionProvider.VisibilityListener Interface
 NO DOC BLOCK: android.app.ActivityOptions Class
 NO DOC BLOCK: android.widget.Advanceable Interface
 NO DOC BLOCK: android.media.audiofx.AutomaticGainControl Class
@@ -34,6 +35,7 @@
 NO DOC BLOCK: android.media.MediaRouter.RouteInfo Class
 NO DOC BLOCK: android.media.MediaRouter.SimpleCallback Class
 NO DOC BLOCK: android.media.MediaRouter.UserRouteInfo Class
+NO DOC BLOCK: android.media.MediaRouter.VolumeCallback Class
 NO DOC BLOCK: android.media.MediaSyncEvent Class
 NO DOC BLOCK: android.nfc.NfcAdapter.CreateBeamUrisCallback Interface
 NO DOC BLOCK: android.media.audiofx.NoiseSuppressor Class
@@ -283,6 +285,7 @@
 NO DOC BLOCK: android.view.ActionMode Method isTitleOptional()
 NO DOC BLOCK: android.animation.LayoutTransition Method isTransitionTypeEnabled(int)
 NO DOC BLOCK: android.view.InputDevice Method isVirtual()
+NO DOC BLOCK: android.view.ActionProvider Method isVisible()
 NO DOC BLOCK: android.view.accessibility.AccessibilityNodeInfo Method isVisibleToUser()
 NO DOC BLOCK: android.database.sqlite.SQLiteDatabase Method isWriteAheadLoggingEnabled()
 NO DOC BLOCK: android.accessibilityservice.AccessibilityServiceInfo Method loadDescription(android.content.pm.PackageManager)
@@ -308,6 +311,7 @@
 NO DOC BLOCK: android.app.Activity Method onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)
 NO DOC BLOCK: android.view.View Method onScreenStateChanged(int)
 NO DOC BLOCK: android.view.View Method onWindowSystemUiVisibilityChanged(int)
+NO DOC BLOCK: android.view.ActionProvider Method overridesItemVisibility()
 NO DOC BLOCK: android.view.View Method performAccessibilityAction(int, android.os.Bundle)
 NO DOC BLOCK: android.view.View.AccessibilityDelegate Method performAccessibilityAction(android.view.View, int, android.os.Bundle)
 NO DOC BLOCK: android.view.accessibility.AccessibilityNodeInfo Method performAction(int, android.os.Bundle)
@@ -324,6 +328,7 @@
 NO DOC BLOCK: android.database.sqlite.SQLiteDatabase Method queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.os.CancellationSignal)
 NO DOC BLOCK: android.database.sqlite.SQLiteDatabase Method rawQuery(java.lang.String, java.lang.String[], android.os.CancellationSignal)
 NO DOC BLOCK: android.database.sqlite.SQLiteDatabase Method rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)
+NO DOC BLOCK: android.view.ActionProvider Method refreshVisibility()
 NO DOC BLOCK: android.content.Loader Method registerOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>)
 NO DOC BLOCK: android.drm.DrmManagerClient Method release()
 NO DOC BLOCK: android.net.wifi.p2p.WifiP2pManager Method removeLocalService(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.nsd.WifiP2pServiceInfo, android.net.wifi.p2p.WifiP2pManager.ActionListener)
@@ -388,6 +393,8 @@
 NO DOC BLOCK: android.widget.Switch Method setSwitchMinWidth(int)
 NO DOC BLOCK: android.widget.Switch Method setSwitchPadding(int)
 NO DOC BLOCK: android.widget.RemoteViews Method setTextViewCompoundDrawables(int, int, int, int, int)
+NO DOC BLOCK: android.widget.RemoteViews Method setTextViewCompoundDrawablesRelative(int, int, int, int, int)
+NO DOC BLOCK: android.widget.RemoteViews Method setTextViewTextSize(int, int, float)
 NO DOC BLOCK: android.widget.Switch Method setThumbDrawable(android.graphics.drawable.Drawable)
 NO DOC BLOCK: android.widget.Switch Method setThumbResource(int)
 NO DOC BLOCK: android.widget.Switch Method setThumbTextPadding(int)
@@ -400,6 +407,8 @@
 NO DOC BLOCK: android.app.Notification.Builder Method setUsesChronometer(boolean)
 NO DOC BLOCK: android.renderscript.Script Method setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[])
 NO DOC BLOCK: android.media.MediaPlayer Method setVideoScalingMode(int)
+NO DOC BLOCK: android.widget.RemoteViews Method setViewPadding(int, int, int, int, int)
+NO DOC BLOCK: android.view.ActionProvider Method setVisibilityListener(android.view.ActionProvider.VisibilityListener)
 NO DOC BLOCK: android.view.accessibility.AccessibilityNodeInfo Method setVisibleToUser(boolean)
 NO DOC BLOCK: android.widget.CalendarView Method setWeekDayTextAppearance(int)
 NO DOC BLOCK: android.widget.CalendarView Method setWeekNumberColor(int)
@@ -485,7 +494,6 @@
 NO DOC BLOCK: android.speech.RecognizerIntent Field EXTRA_SECURE
 NO DOC BLOCK: android.content.pm.PackageManager Field FEATURE_TELEVISION
 NO DOC BLOCK: android.content.Intent Field FILL_IN_CLIP_DATA
-NO DOC BLOCK: android.content.Intent Field FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS
 NO DOC BLOCK: android.accessibilityservice.AccessibilityServiceInfo Field FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
 NO DOC BLOCK: android.content.pm.ServiceInfo Field FLAG_ISOLATED_PROCESS
 NO DOC BLOCK: android.content.Intent Field FLAG_RECEIVER_FOREGROUND
@@ -538,6 +546,7 @@
 NO DOC BLOCK: android.media.MediaPlayer Field MEDIA_MIMETYPE_TEXT_SUBRIP
 NO DOC BLOCK: android.content.Context Field MEDIA_ROUTER_SERVICE
 NO DOC BLOCK: android.R.attr Field mediaRouteButtonStyle
+NO DOC BLOCK: android.R.attr Field mediaRouteTypes
 NO DOC BLOCK: android.provider.CalendarContract.RemindersColumns Field METHOD_ALARM
 NO DOC BLOCK: android.content.ClipDescription Field MIMETYPE_TEXT_HTML
 NO DOC BLOCK: android.content.Context Field MODE_ENABLE_WRITE_AHEAD_LOGGING
diff --git a/docs/html/sdk/api_diff/16/user_comments_for_15_to_16.xml b/docs/html/sdk/api_diff/16/user_comments_for_15_to_16.xml
index 4852d37..ee16273 100644
--- a/docs/html/sdk/api_diff/16/user_comments_for_15_to_16.xml
+++ b/docs/html/sdk/api_diff/16/user_comments_for_15_to_16.xml
@@ -142,6 +142,12 @@
   </text>
 </comment>
 <comment>
+  <identifier id="android.R.attr.mediaRouteTypes"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.R.attr.parentActivityName"/>
   <text>
     InsertCommentsHere
@@ -1252,12 +1258,6 @@
   </text>
 </comment>
 <comment>
-  <identifier id="android.content.Intent.FLAG_ACTIVITY_CLOSE_SYSTEM_DIALOGS"/>
-  <text>
-    InsertCommentsHere
-  </text>
-</comment>
-<comment>
   <identifier id="android.content.Intent.FLAG_RECEIVER_FOREGROUND"/>
   <text>
     InsertCommentsHere
@@ -2506,6 +2506,12 @@
   </text>
 </comment>
 <comment>
+  <identifier id="android.media.MediaRouter.VolumeCallback"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.media.MediaSyncEvent"/>
   <text>
     InsertCommentsHere
@@ -4624,6 +4630,18 @@
   </text>
 </comment>
 <comment>
+  <identifier id="android.view.ActionProvider.VisibilityListener"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
+  <identifier id="android.view.ActionProvider.isVisible_added()"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.view.ActionProvider.onCreateActionView_added(android.view.MenuItem)"/>
   <text>
     InsertCommentsHere
@@ -4636,6 +4654,24 @@
   </text>
 </comment>
 <comment>
+  <identifier id="android.view.ActionProvider.overridesItemVisibility_added()"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
+  <identifier id="android.view.ActionProvider.refreshVisibility_added()"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
+  <identifier id="android.view.ActionProvider.setVisibilityListener_added(android.view.ActionProvider.VisibilityListener)"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.view.Choreographer"/>
   <text>
     InsertCommentsHere
@@ -6214,12 +6250,30 @@
   </text>
 </comment>
 <comment>
+  <identifier id="android.widget.RemoteViews.setTextViewCompoundDrawablesRelative_added(int, int, int, int, int)"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.widget.RemoteViews.setTextViewCompoundDrawables_added(int, int, int, int, int)"/>
   <text>
     InsertCommentsHere
   </text>
 </comment>
 <comment>
+  <identifier id="android.widget.RemoteViews.setTextViewTextSize_added(int, int, float)"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
+  <identifier id="android.widget.RemoteViews.setViewPadding_added(int, int, int, int, int)"/>
+  <text>
+    InsertCommentsHere
+  </text>
+</comment>
+<comment>
   <identifier id="android.widget.SearchView"/>
   <text>
     InsertCommentsHere
diff --git a/docs/html/sdk/download.jd b/docs/html/sdk/download.jd
new file mode 100644
index 0000000..8005009
--- /dev/null
+++ b/docs/html/sdk/download.jd
@@ -0,0 +1,92 @@
+page.title=Download an Archived Android SDK
+hide_license_footer=true
+
+@jd:body
+
+<script type="text/javascript">
+  function verify() {
+    document.getElementById('download-button').disabled =
+!document.getElementById('checkbox').checked;
+  }
+  function submit() {
+    var location = window.location.href;
+    if (location.indexOf('?v=') != -1) {
+      var filename = location.substring(location.indexOf('=')+1,location.length);
+      if (document.getElementById('checkbox').checked) {
+        document.location = "http://dl.google.com/android/" + filename;
+      }
+      document.getElementById('click-download').setAttribute("href", "http://dl.google.com/android/"
++ filename);
+      $("#terms-form").hide(500);
+      $("#next-steps").show(500);
+      document.getElementById('checkbox').disabled=true;
+      document.getElementById('download-button').disabled=true;
+    } else {
+      alert("You have not selected an SDK version. Please return to the SDK Archives page");
+    }
+  }
+</script>
+
+<div id="terms-form">
+    <p>Please carefully review the Android SDK License Agreement before downloading the SDK.
+The License Agreement constitutes a contract between you and Google with respect to your use of the
+SDK.</p>
+    <p class="note"><strong>Note:</strong> You must agree to this license agreement in order to
+download one of the archived SDKs, because these SDK packages contain Google software (whereas, the
+<a href="http://developer.android.com/sdk/index.html">current SDK</a> packages do not require a
+license agreement, because they contain only the open sourced SDK tools).</p>
+
+  <iframe id="terms" style="border:1px solid #888;margin:0 0 1em;height:400px;width:100%;"
+src="terms_body.html">
+  </iframe>
+
+  <p>
+    <input type="checkbox" id="checkbox" onclick="verify()" />
+    <label for="checkbox">I agree to the terms of the Android SDK License Agreement.</label>
+  </p>
+  <p>
+    <input type="submit" value="Download" id="download-button" disabled="disabled"
+onclick="submit()" />
+  </p>
+  <p>
+  <script language="javascript">
+    var loc = window.location.href;
+    if (loc.indexOf('?v=') != -1) {
+      var filename = loc.substring(loc.indexOf('=')+1,loc.length);
+      document.write("File: " + filename);
+    }
+  </script>
+  </p>
+</div><!-- end terms-form -->
+
+<noscript>
+  <p><strong>Please enable Javascript in your browser in order to agree to the terms and download
+the SDK.</strong></p>
+</noscript>
+
+<div class="special" id="next-steps" style="display:none">
+  <p>Your download should be underway. If not, <a id="click-download">click here to start the
+download</a>.</p>
+  <p>Beware that you've just downloaded a very old version of the Android SDK, which is not
+recommended. We no longer maintain documentation about how to install these archived SDKs nor
+support the tools contained within.</p>
+  <p>We recommend that you instead download the latest <a
+href="http://developer.android.com/sdk/index.html">Android SDK starter package</a>, which includes
+the latest SDK tools and allows you to develop against any version of the Android platform, back to
+Android 1.1.</p>
+</div>
+
+<script type="text/javascript">
+  var loc = window.location.href;
+  var filename = loc.substring(loc.indexOf('=')+1,loc.length);
+  version = filename.substring(filename.indexOf('.')-1,filename.lastIndexOf('.'));
+  $(".addVersionPath").each(function(i) {
+    var oldHref = $(this).attr("href");
+    $(this).attr({href: "/sdk/" + version + "/" + oldHref});
+  });
+</script>
+
+
+
+
+
diff --git a/docs/html/sdk/terms_body.html b/docs/html/sdk/terms_body.html
new file mode 100644
index 0000000..35e1655
--- /dev/null
+++ b/docs/html/sdk/terms_body.html
@@ -0,0 +1,337 @@
+
+
+ 
+<p>This is the Android Software Development Kit License Agreement.</p> 
+ 
+<h2> 
+	1. Introduction
+</h2> 
+<p> 
+	1.1 The Android Software Development Kit (referred to in this License Agreement as the "SDK"
+and specifically including the Android system files, packaged APIs, and Google APIs add-ons) is
+licensed to you subject to the terms of this License Agreement. This License Agreement forms a
+legally binding contract between you and Google in relation to your use of the SDK.
+ 
+</p> 
+<p> 
+	1.2 "Google" means Google Inc., a Delaware corporation with principal place of business at
+1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+</p> 
+<h2> 
+	2. Accepting this License Agreement
+</h2> 
+<p> 
+	2.1 In order to use the SDK, you must first agree to this License Agreement. You may not use
+the SDK if you do not accept this License Agreement.
+</p> 
+<p> 
+	2.2 You can accept this License Agreement by:
+</p> 
+<p> 
+	(A) clicking to accept or agree to this License Agreement, where this option is made
+available to you; or
+</p> 
+<p> 
+	(B) by actually using the SDK. In this case, you agree that use of the SDK constitutes
+acceptance of the Licensing Agreement from that point onwards.
+</p> 
+<p> 
+	2.3 You may not use the SDK and may not accept the Licensing Agreement if you are a person
+barred from receiving the SDK under the laws of the United States or other countries including the
+country in which you are resident or from which you use the SDK.
+</p> 
+<p> 
+	2.4 If you are agreeing to be bound by this License Agreement on behalf of your employer or
+other entity, you represent and warrant that you have full legal authority to bind your employer or
+such entity to this License Agreement. If you do not have the requisite authority, you may not
+accept the Licensing Agreement or use the SDK on behalf of your employer or other entity.
+</p> 
+<h2> 
+	3. SDK License from Google
+</h2> 
+<p> 
+	3.1 Subject to the terms of this License Agreement, Google grants you a limited, worldwide,
+royalty-free, non- assignable and non-exclusive license to use the SDK solely to develop
+applications to run on the Android platform.
+</p> 
+<p> 
+	3.2 You agree that Google or third parties own all legal right, title and interest in and to
+the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property
+Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law,
+and any and all other proprietary rights. Google reserves all rights not expressly granted to you. 
+ 
+</p> 
+<p> 
+	3.3 Except to the extent required by applicable third party licenses, you may not copy
+(except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble,
+or create derivative works of the SDK or any part of the SDK. Except to the extent required by
+applicable third party licenses, you may not load any part of the SDK onto a mobile handset or any
+other hardware device except a personal computer, combine any part of the SDK with other software,
+or distribute any software or device incorporating a part of the SDK. 
+</p> 
+<p> 
+	3.4 Use, reproduction and distribution of components of the SDK licensed under an open
+source software license are governed solely by the terms of that open source software license and
+not this License Agreement.
+</p> 
+<p> 
+	3.5 You agree that the form and nature of the SDK that Google provides may change without
+prior notice to you and that future versions of the SDK may be incompatible with applications
+developed on previous versions of the SDK. You agree that Google may stop (permanently or
+temporarily) providing the SDK (or any features within the SDK) to you or to users generally at
+Google's sole discretion, without prior notice to you.
+</p> 
+<p> 
+	3.6 Nothing in this License Agreement gives you a right to use any of Google's trade names,
+trademarks, service marks, logos, domain names, or other distinctive brand features.
+</p> 
+<p> 
+	3.7 You agree that you will not remove, obscure, or alter any proprietary rights notices
+(including copyright and trademark notices) that may be affixed to or contained within the SDK.
+</p> 
+<h2> 
+	4. Use of the SDK by You
+</h2> 
+<p> 
+	4.1 Google agrees that it obtains no right, title or interest from you (or your licensors)
+under this License Agreement in or to any software applications that you develop using the SDK,
+including any intellectual property rights that subsist in those applications. 
+</p> 
+<p> 
+	4.2 You agree to use the SDK and write applications only for purposes that are permitted by
+(a) this License Agreement and (b) any applicable law, regulation or generally accepted practices or
+guidelines in the relevant jurisdictions (including any laws regarding the export of data or
+software to and from the United States or other relevant countries).
+</p> 
+<p> 
+	4.3 You agree that if you use the SDK to develop applications for general public users, you
+will protect the privacy and legal rights of those users. If the users provide you with user names,
+passwords, or other login information or personal information, your must make the users aware that
+the information will be available to your application, and you must provide legally adequate privacy
+notice and protection for those users. If your application stores personal or sensitive information
+provided by users, it must do so securely. If the user provides your application with Google Account
+information, your application may only use that information to access the user's Google Account
+when, and for the limited purposes for which, the user has given you permission to do so.
+</p> 
+<p> 
+	4.4 You agree that you will not engage in any activity with the SDK, including the
+development or distribution of an application, that interferes with, disrupts, damages, or accesses
+in an unauthorized manner the servers, networks, or other properties or services of any third party
+including, but not limited to, Google or any mobile communications carrier.
+</p> 
+<p> 
+	4.5 You agree that you are solely responsible for (and that Google has no responsibility to
+you or to any third party for) any data, content, or resources that you create, transmit or display
+through the Android platform and/or applications for the Android platform, and for the consequences
+of your actions (including any loss or damage which Google may suffer) by doing so.
+</p> 
+<p> 
+	4.6 You agree that you are solely responsible for (and that Google has no responsibility to
+you or to any third party for) any breach of your obligations under this License Agreement, any
+applicable third party contract or Terms of Service, or any applicable law or regulation, and for
+the consequences (including any loss or damage which Google or any third party may suffer) of any
+such breach.
+</p> 
+<h2> 
+	5. Your Developer Credentials
+</h2> 
+<p> 
+	5.1 You agree that you are responsible for maintaining the confidentiality of any developer
+credentials that may be issued to you by Google or which you may choose yourself and that you will
+be solely responsible for all applications that are developed under your developer credentials.
+</p> 
+<h2> 
+	6. Privacy and Information
+</h2> 
+<p> 
+	6.1 In order to continually innovate and improve the SDK, Google may collect certain usage
+statistics from the software including but not limited to a unique identifier, associated IP
+address, version number of the software, and information on which tools and/or services in the SDK
+are being used and how they are being used. Before any of this information is collected, the SDK
+will notify you and seek your consent. If you withhold consent, the information will not be
+collected.
+</p> 
+<p> 
+	6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in
+accordance with Google's Privacy Policy.
+</p> 
+<h2> 
+	7. Third Party Applications for the Android Platform
+</h2> 
+<p> 
+	7.1 If you use the SDK to run applications developed by a third party or that access data,
+content or resources provided by a third party, you agree that Google is not responsible for those
+applications, data, content, or resources. You understand that all data, content or resources which
+you may access through such third party applications are the sole responsibility of the person from
+which they originated and that Google is not liable for any loss or damage that you may experience
+as a result of the use or access of any of those third party applications, data, content, or
+resources.
+</p> 
+<p> 
+	7.2 You should be aware the data, content, and resources presented to you through such a
+third party application may be protected by intellectual property rights which are owned by the
+providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan,
+sell, distribute or create derivative works based on these data, content, or resources (either in
+whole or in part) unless you have been specifically given permission to do so by the relevant
+owners.
+</p> 
+<p> 
+	7.3 You acknowledge that your use of such third party applications, data, content, or
+resources may be subject to separate terms between you and the relevant third party. In that case,
+this License Agreement does not affect your legal relationship with these third parties.
+</p> 
+<h2> 
+	8. Using Android APIs
+</h2> 
+<p> 
+	8.1 Google Data APIs
+</p> 
+<p> 
+	8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be
+protected by intellectual property rights which are owned by Google or those parties that provide
+the data (or by other persons or companies on their behalf). Your use of any such API may be subject
+to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create
+derivative works based on this data (either in whole or in part) unless allowed by the relevant
+Terms of Service.
+</p> 
+<p> 
+	8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree
+that you shall retrieve data only with the user's explicit consent and only when, and for the
+limited purposes for which, the user has given you permission to do so. 
+ 
+</p> 
+<h2> 
+	9. Terminating this License Agreement
+</h2> 
+<p> 
+	9.1 This License Agreement will continue to apply until terminated by either you or Google
+as set out below.
+</p> 
+<p> 
+	9.2 If you want to terminate this License Agreement, you may do so by ceasing your use of
+the SDK and any relevant developer credentials.
+</p> 
+<p> 
+	9.3 Google may at any time, terminate this License Agreement with you if:
+</p> 
+<p> 
+	(A) you have breached any provision of this License Agreement; or
+</p> 
+<p> 
+	(B) Google is required to do so by law; or
+</p> 
+<p> 
+	(C) the partner with whom Google offered certain parts of SDK (such as APIs) to you has
+terminated its relationship with Google or ceased to offer certain parts of the SDK to you; or
+</p> 
+<p> 
+	(D) Google decides to no longer providing the SDK or certain parts of the SDK to users in
+the country in which you are resident or from which you use the service, or the provision of the SDK
+or certain SDK services to you by Google is, in Google's sole discretion, no longer commercially
+viable.
+</p> 
+<p> 
+	9.4 When this License Agreement comes to an end, all of the legal rights, obligations and
+liabilities that you and Google have benefited from, been subject to (or which have accrued over
+time whilst this License Agreement has been in force) or which are expressed to continue
+indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall
+continue to apply to such rights, obligations and liabilities indefinitely.
+</p> 
+<h2> 
+	10. DISCLAIMER OF WARRANTIES
+</h2> 
+<p> 
+	10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND
+THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+</p> 
+<p> 
+	10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE
+OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR
+COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE.
+</p> 
+<p> 
+	10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER
+EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+</p> 
+<h2> 
+	11. LIMITATION OF LIABILITY
+</h2> 
+<p> 
+	11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND
+ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY
+LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN
+AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+</p> 
+<h2> 
+	12. Indemnification
+</h2> 
+<p> 
+	12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold
+harmless Google, its affiliates and their respective directors, officers, employees and agents from
+and against any and all claims, actions, suits or proceedings, as well as any and all losses,
+liabilities, damages, costs and expenses (including reasonable attorneys fees) arising out of or
+accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any
+copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any
+person or defames any person or violates their rights of publicity or privacy, and (c) any
+non-compliance by you with this License Agreement.
+</p> 
+<h2> 
+	13. Changes to the License Agreement
+</h2> 
+<p> 
+	13.1 Google may make changes to the License Agreement as it distributes new versions of the
+SDK. When these changes are made, Google will make a new version of the License Agreement available
+on the website where the SDK is made available.
+</p> 
+<h2> 
+	14. General Legal Terms
+</h2> 
+<p> 
+	14.1 This License Agreement constitute the whole legal agreement between you and Google and
+govern your use of the SDK (excluding any services which Google may provide to you under a separate
+written agreement), and completely replace any prior agreements between you and Google in relation
+to the SDK.
+</p> 
+<p> 
+	14.2 You agree that if Google does not exercise or enforce any legal right or remedy which
+is contained in this License Agreement (or which Google has the benefit of under any applicable
+law), this will not be taken to be a formal waiver of Google's rights and that those rights or
+remedies will still be available to Google.
+</p> 
+<p> 
+	14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any
+provision of this License Agreement is invalid, then that provision will be removed from this
+License Agreement without affecting the rest of this License Agreement. The remaining provisions of
+this License Agreement will continue to be valid and enforceable.
+</p> 
+<p> 
+	14.4 You acknowledge and agree that each member of the group of companies of which Google is
+the parent shall be third party beneficiaries to this License Agreement and that such other
+companies shall be entitled to directly enforce, and rely upon, any provision of this License
+Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person
+or company shall be third party beneficiaries to this License Agreement.
+</p> 
+<p> 
+	14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS.
+YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE
+SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+</p> 
+<p> 
+	14.6 The rights granted in this License Agreement may not be assigned or transferred by
+either you or Google without the prior written approval of the other party. Neither you nor Google
+shall be permitted to delegate their responsibilities or obligations under this License Agreement
+without the prior written approval of the other party.
+</p> 
+<p> 
+	14.7 This License Agreement, and your relationship with Google under this License Agreement,
+shall be governed by the laws of the State of California without regard to its conflict of laws
+provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located
+within the county of Santa Clara, California to resolve any legal matter arising from this License
+Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for
+injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+</p> 
+<p> 
+	<em>April 10, 2009</em> 
+</p> 
\ No newline at end of file
diff --git a/docs/html/tools/index.jd b/docs/html/tools/index.jd
index 3fc9bfe..04e0d3b 100644
--- a/docs/html/tools/index.jd
+++ b/docs/html/tools/index.jd
@@ -34,7 +34,7 @@
     
   <ul>
     <li>Build rich Android UI with drag and drop. 
-    <li>Vsualize your UI on tablets, phones, and other devices. Switch themes, locales, even plaform versions instantly, without building.</li>
+    <li>Visualize your UI on tablets, phones, and other devices. Switch themes, locales, even platform versions instantly, without building.</li>
     <li>Visual refactoring lets you extracts layout for inclusion, convert layouts, extract styles</li>
     <li>Editor support for working with custom UI components</li>
   </ul>
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index e57c221..db0cbab 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -48,11 +48,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png"
-class="toggle-content-img" alt="" />
-    Revision 3</a> <em>(March 2012)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Revision 3</a> <em>(March 2012)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
 
     <p>Maintenance update. The system version is 4.0.4.</p>
     <p class="note"><strong>Note:</strong> This system image includes support for emulator
@@ -70,11 +69,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    Revision 2</a> <em>(January 2012)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Revision 2</a> <em>(January 2012)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
 
     <p>Maintenance update. The system version is 4.0.3.</p>
     <dl>
@@ -89,11 +87,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    Revision 1</a> <em>(December 2011)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Revision 1</a> <em>(December 2011)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
 
     <p>Initial release. The system version is 4.0.3.</p>
     <dl>
@@ -169,11 +166,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    Android 4.0, Revision 2</a> <em>(December 2011)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Android 4.0, Revision 2</a> <em>(December 2011)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
     <p>Maintenance update. The system version is 4.0.2.</p>
     <dl>
       <dt>Dependencies:</dt>
@@ -186,11 +182,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    Android 4.0, Revision 1</a> <em>(October 2011)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Android 4.0, Revision 1</a> <em>(October 2011)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
     <p>Initial release. The system version is 4.0.1.</p>
     <dl>
       <dt>Dependencies:</dt>
@@ -264,11 +259,10 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-    Android 3.2, Revision 1</a> <em>(July 2011)</em>
-  </a></p>
+class="toggle-content-img" alt="" />Android 3.2, Revision 1</a> <em>(July 2011)</em>
+  </p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
 
 <dl>
 <dt>Initial release. SDK Tools r12 or higher is recommended.</dt>
@@ -319,11 +313,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 3.1, Revision 3</a> <em>(July 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 3.1, Revision 3</a> <em>(July 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -348,11 +341,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 3.1, Revision 2</a> <em>(May 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 3.1, Revision 2</a> <em>(May 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -375,11 +367,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 3.1, Revision 1</a> <em>(May 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 3.1, Revision 1</a> <em>(May 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -425,11 +416,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 3.0, Revision 2</a> <em>(July 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 3.0, Revision 2</a> <em>(July 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -452,11 +442,11 @@
 <div class="toggle-content closed">
 
 <p><a href="#" onclick="return toggleContent(this)">
-  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt="" />
-  Android 3.0, Revision 1</a> <em>(February 2011)</em>
-</a></p>
+  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" 
+       alt="" />Android 3.0, Revision 1</a> <em>(February 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
     
 <dl>
 <dt>Dependencies:</dt>
@@ -510,11 +500,11 @@
 <div class="toggle-content closed" >
 
 <p><a href="#" onclick="return toggleContent(this)">
-  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt="" />
-        Android 2.3.4, Revision 1</a> <em>(May 2011)</em>
-</a></p>
+  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" 
+       alt="" />Android 2.3.4, Revision 1</a> <em>(May 2011)</em>
+</p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
     <dl>
       <dt>Dependencies:</dt>
       <dd>
@@ -571,11 +561,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 2.3.3, Revision 2</a> <em>(July 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 2.3.3, Revision 2</a> <em>(July 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -599,11 +588,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android 2.3.3, Revision 1</a> <em>(February 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android 2.3.3, Revision 1</a> <em>(February 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 <dl>
 <dt>Dependencies:</dt>
 <dd>
@@ -667,11 +655,11 @@
 <div class="toggle-content closed" >
 
 <p><a href="#" onclick="return toggleContent(this)">
-  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt="" />
-        Android 2.3, Revision 1</a> <em>(December 2010)</em>
-</a></p>
+  <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" 
+       alt="" />Android 2.3, Revision 1</a> <em>(December 2010)</em>
+</p>
 
-  <div class="toggle-content-toggleme" style="padding-left:2em;">
+  <div class="toggle-content-toggleme">
     <dl>
       <dt>Dependencies:</dt>
       <dd>
@@ -724,11 +712,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android {@sdkPlatformVersion}, Revision 3</a> <em>(July 2011)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android {@sdkPlatformVersion}, Revision 3</a> <em>(July 2011)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 
 <dl>
 <dt>Dependencies:</dt>
@@ -752,11 +739,10 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android {@sdkPlatformVersion}, Revision 2</a> <em>(July 2010)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android {@sdkPlatformVersion}, Revision 2</a> <em>(July 2010)</em>
+</p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 <dt>Dependencies:</dt>
 <dd>
 <p>Requires SDK Tools r6 or higher.</p>
@@ -781,11 +767,9 @@
 
 <p><a href="#" onclick="return toggleContent(this)">
   <img src="{@docRoot}assets/images/triangle-closed.png"
-class="toggle-content-img" alt="" />
-  Android {@sdkPlatformVersion}, Revision 1</a> <em>(May 2010)</em>
-</a></p>
+class="toggle-content-img" alt="" />Android {@sdkPlatformVersion}, Revision 1</a> <em>(May 2010)</em></p>
 
-<div class="toggle-content-toggleme" style="padding-left:2em;">
+<div class="toggle-content-toggleme">
 <dl>
 <dt>Dependencies:</dt>
 <dd>
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 5ec3983..a54c188 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -40,12 +40,19 @@
 		external/skia/include/utils
 
 	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
-	LOCAL_CFLAGS += -fvisibility=hidden
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 	LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
 	LOCAL_MODULE := libhwui
 	LOCAL_MODULE_TAGS := optional
-	
+
+	ifndef HWUI_COMPILE_SYMBOLS
+		LOCAL_CFLAGS += -fvisibility=hidden
+	endif
+
+	ifdef HWUI_COMPILE_FOR_PERF
+		LOCAL_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
+	endif
+
 	include $(BUILD_SHARED_LIBRARY)
 
     include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 56eb317..258ced0 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -358,7 +358,7 @@
     }
 }
 
-void Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
+bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) {
     if (scissorEnabled && (x != mScissorX || y != mScissorY ||
             width != mScissorWidth || height != mScissorHeight)) {
 
@@ -368,21 +368,28 @@
         mScissorY = y;
         mScissorWidth = width;
         mScissorHeight = height;
+
+        return true;
     }
+    return false;
 }
 
-void Caches::enableScissor() {
+bool Caches::enableScissor() {
     if (!scissorEnabled) {
         glEnable(GL_SCISSOR_TEST);
         scissorEnabled = true;
+        return true;
     }
+    return false;
 }
 
-void Caches::disableScissor() {
+bool Caches::disableScissor() {
     if (scissorEnabled) {
         glDisable(GL_SCISSOR_TEST);
         scissorEnabled = false;
+        return true;
     }
+    return false;
 }
 
 void Caches::setScissorEnabled(bool enabled) {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 5e09d94..4cbac41 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -197,15 +197,15 @@
     /**
      * Sets the scissor for the current surface.
      */
-    void setScissor(GLint x, GLint y, GLint width, GLint height);
+    bool setScissor(GLint x, GLint y, GLint width, GLint height);
 
     /**
      * Resets the scissor state.
      */
     void resetScissor();
 
-    void enableScissor();
-    void disableScissor();
+    bool enableScissor();
+    bool disableScissor();
     void setScissorEnabled(bool enabled);
 
     /**
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 55a860e..7d150bb 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -65,9 +65,15 @@
 // Turn on to enable additional debugging in the font renderers
 #define DEBUG_FONT_RENDERER 0
 
+// Force gamma correction in shaders
+#define DEBUG_FONT_RENDERER_FORCE_SHADER_GAMMA 0
+
 // Turn on to dump display list state
 #define DEBUG_DISPLAY_LIST 0
 
+// Turn on to insert an event marker for each display list op
+#define DEBUG_DISPLAY_LIST_OPS_AS_EVENTS 0
+
 #if DEBUG_INIT
     #define INIT_LOGD(...) ALOGD(__VA_ARGS__)
 #else
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 841a35b..133f63f 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -852,11 +852,13 @@
 #endif
 
     renderer.startMark(mName.string());
+
     int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
     setViewProperties(renderer, level);
-    if (renderer.quickReject(0, 0, mWidth, mHeight)) {
+
+    if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
         DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
         renderer.restoreToCount(restoreTo);
         renderer.endMark();
@@ -865,6 +867,7 @@
 
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     int saveCount = renderer.getSaveCount() - 1;
+
     while (!mReader.eof()) {
         int op = mReader.readInt();
         if (op & OP_MAY_BE_SKIPPED_MASK) {
@@ -880,6 +883,10 @@
         }
         logBuffer.writeCommand(level, op);
 
+#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
+        Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]);
+#endif
+
         switch (op) {
             case DrawGLFunction: {
                 Functor *functor = (Functor *) getInt();
@@ -1545,7 +1552,7 @@
 
 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
-    const bool reject = quickReject(left, top, left + bitmap->width(), bitmap->height());
+    const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
     uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
     addBitmapData(bitmap);
     addPoint(left, top);
@@ -1652,7 +1659,10 @@
     uint32_t width, height;
     computePathBounds(path, paint, left, top, offset, width, height);
 
-    const bool reject = quickReject(left - offset, top - offset, width, height);
+    left -= offset;
+    top -= offset;
+
+    const bool reject = quickReject(left, top, left + width, top + height);
     uint32_t* location = addOp(DisplayList::DrawPath, reject);
     addPath(path);
     addPaint(paint);
diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp
index 75d5b10..226f4bc 100644
--- a/libs/hwui/GammaFontRenderer.cpp
+++ b/libs/hwui/GammaFontRenderer.cpp
@@ -24,6 +24,18 @@
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
+// Utils
+///////////////////////////////////////////////////////////////////////////////
+
+static int luminance(const SkPaint* paint) {
+    uint32_t c = paint->getColor();
+    const int r = (c >> 16) & 0xFF;
+    const int g = (c >>  8) & 0xFF;
+    const int b = (c      ) & 0xFF;
+    return (r * 2 + g * 5 + b) >> 3;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Base class GammaFontRenderer
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -36,7 +48,11 @@
         }
     }
 
+#if DEBUG_FONT_RENDERER_FORCE_SHADER_GAMMA
+    return new ShaderGammaFontRenderer();
+#else
     return new LookupGammaFontRenderer();
+#endif
 }
 
 GammaFontRenderer::GammaFontRenderer() {
@@ -82,6 +98,29 @@
 
 ShaderGammaFontRenderer::ShaderGammaFontRenderer(): GammaFontRenderer() {
     INIT_LOGD("Creating shader gamma font renderer");
+    mRenderer = NULL;
+}
+
+void ShaderGammaFontRenderer::describe(ProgramDescription& description,
+        const SkPaint* paint) const {
+    if (paint->getShader() == NULL) {
+        const int l = luminance(paint);
+
+        if (l <= mBlackThreshold) {
+            description.hasGammaCorrection = true;
+            description.gamma = mGamma;
+        } else if (l >= mWhiteThreshold) {
+            description.hasGammaCorrection = true;
+            description.gamma = 1.0f / mGamma;
+        }
+    }
+}
+
+void ShaderGammaFontRenderer::setupProgram(ProgramDescription& description,
+        Program* program) const {
+    if (description.hasGammaCorrection) {
+        glUniform1f(program->getUniform("gamma"), description.gamma);
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -164,15 +203,11 @@
 
 FontRenderer& LookupGammaFontRenderer::getFontRenderer(const SkPaint* paint) {
     if (paint->getShader() == NULL) {
-        uint32_t c = paint->getColor();
-        const int r = (c >> 16) & 0xFF;
-        const int g = (c >>  8) & 0xFF;
-        const int b = (c      ) & 0xFF;
-        const int luminance = (r * 2 + g * 5 + b) >> 3;
+        const int l = luminance(paint);
 
-        if (luminance <= mBlackThreshold) {
+        if (l <= mBlackThreshold) {
             return *getRenderer(kGammaBlack);
-        } else if (luminance >= mWhiteThreshold) {
+        } else if (l >= mWhiteThreshold) {
             return *getRenderer(kGammaWhite);
         }
     }
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
index 988947a..8e1db78 100644
--- a/libs/hwui/GammaFontRenderer.h
+++ b/libs/hwui/GammaFontRenderer.h
@@ -20,6 +20,7 @@
 #include <SkPaint.h>
 
 #include "FontRenderer.h"
+#include "Program.h"
 
 namespace android {
 namespace uirenderer {
@@ -34,9 +35,11 @@
     virtual FontRenderer& getFontRenderer(const SkPaint* paint) = 0;
 
     virtual uint32_t getFontRendererCount() const = 0;
-
     virtual uint32_t getFontRendererSize(uint32_t fontRenderer) const = 0;
 
+    virtual void describe(ProgramDescription& description, const SkPaint* paint) const = 0;
+    virtual void setupProgram(ProgramDescription& description, Program* program) const = 0;
+
     static GammaFontRenderer* createRenderer();
 
 protected:
@@ -79,6 +82,9 @@
         return mRenderer->getCacheSize();
     }
 
+    void describe(ProgramDescription& description, const SkPaint* paint) const;
+    void setupProgram(ProgramDescription& description, Program* program) const;
+
 private:
     ShaderGammaFontRenderer();
 
@@ -109,6 +115,12 @@
         return renderer->getCacheSize();
     }
 
+    void describe(ProgramDescription& description, const SkPaint* paint) const {
+    }
+
+    void setupProgram(ProgramDescription& description, Program* program) const {
+    }
+
 private:
     LookupGammaFontRenderer();
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 99016d6..a47d732 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -313,6 +313,7 @@
     interrupt();
     detachFunctor(functor);
 
+    mCaches.enableScissor();
     if (mDirtyClip) {
         setScissorFromClip();
     }
@@ -982,7 +983,7 @@
         // The list contains bounds that have already been clipped
         // against their initial clip rect, and the current clip
         // is likely different so we need to disable clipping here
-        mCaches.disableScissor();
+        bool scissorChanged = mCaches.disableScissor();
 
         Vertex mesh[count * 6];
         Vertex* vertex = mesh;
@@ -1009,6 +1010,8 @@
         setupDrawVertices(&mesh[0].position[0]);
 
         glDrawArrays(GL_TRIANGLES, 0, count * 6);
+
+        if (scissorChanged) mCaches.enableScissor();
     } else {
         for (uint32_t i = 0; i < count; i++) {
             delete mLayers.itemAt(i);
@@ -1065,16 +1068,31 @@
     Rect clip(*mSnapshot->clipRect);
     clip.snapToPixelBoundaries();
 
-    mCaches.setScissor(clip.left, mSnapshot->height - clip.bottom,
-            clip.getWidth(), clip.getHeight());
-
-    mDirtyClip = false;
+    if (mCaches.setScissor(clip.left, mSnapshot->height - clip.bottom,
+            clip.getWidth(), clip.getHeight())) {
+        mDirtyClip = false;
+    }
 }
 
 const Rect& OpenGLRenderer::getClipBounds() {
     return mSnapshot->getLocalClip();
 }
 
+bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom) {
+    if (mSnapshot->isIgnored()) {
+        return true;
+    }
+
+    Rect r(left, top, right, bottom);
+    mSnapshot->transform->mapRect(r);
+    r.snapToPixelBoundaries();
+
+    Rect clipRect(*mSnapshot->clipRect);
+    clipRect.snapToPixelBoundaries();
+
+    return !clipRect.intersects(r);
+}
+
 bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
     if (mSnapshot->isIgnored()) {
         return true;
@@ -1112,6 +1130,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setupDraw(bool clear) {
+    // TODO: It would be best if we could do this before quickReject()
+    //       changes the scissor test state
     if (clear) clearLayerRegions();
     if (mDirtyClip) {
         setScissorFromClip();
@@ -1174,6 +1194,10 @@
     mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA);
 }
 
+void OpenGLRenderer::setupDrawTextGamma(const SkPaint* paint) {
+    mCaches.fontRenderer->describe(mDescription, paint);
+}
+
 void OpenGLRenderer::setupDrawColor(float r, float g, float b, float a) {
     mColorA = a;
     mColorR = r;
@@ -1301,6 +1325,10 @@
     }
 }
 
+void OpenGLRenderer::setupDrawTextGammaUniforms() {
+    mCaches.fontRenderer->setupProgram(mDescription, mCaches.currentProgram);
+}
+
 void OpenGLRenderer::setupDrawSimpleMesh() {
     bool force = mCaches.bindMeshBuffer();
     mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, 0);
@@ -2302,6 +2330,7 @@
 
     mCaches.activeTexture(0);
     setupDraw();
+    setupDrawTextGamma(paint);
     setupDrawDirtyRegionsDisabled();
     setupDrawWithTexture(true);
     setupDrawAlpha8Color(paint->getColor(), alpha);
@@ -2314,6 +2343,7 @@
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
     setupDrawShaderUniforms(pureTranslate);
+    setupDrawTextGammaUniforms();
 
     const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
@@ -2387,6 +2417,8 @@
     if (CC_UNLIKELY(mHasShadow)) {
         mCaches.activeTexture(0);
 
+        // NOTE: The drop shadow will not perform gamma correction
+        //       if shader-based correction is enabled
         mCaches.dropShadowCache.setFontRenderer(fontRenderer);
         const ShadowTexture* shadow = mCaches.dropShadowCache.get(
                 paint, text, bytesCount, count, mShadowRadius);
@@ -2427,6 +2459,7 @@
     // The font renderer will always use texture unit 0
     mCaches.activeTexture(0);
     setupDraw();
+    setupDrawTextGamma(paint);
     setupDrawDirtyRegionsDisabled();
     setupDrawWithTexture(true);
     setupDrawAlpha8Color(paint->getColor(), alpha);
@@ -2441,6 +2474,7 @@
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
     setupDrawShaderUniforms(pureTranslate);
+    setupDrawTextGammaUniforms();
 
     const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
@@ -2485,6 +2519,7 @@
 
     mCaches.activeTexture(0);
     setupDraw();
+    setupDrawTextGamma(paint);
     setupDrawDirtyRegionsDisabled();
     setupDrawWithTexture(true);
     setupDrawAlpha8Color(paint->getColor(), alpha);
@@ -2497,6 +2532,7 @@
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
     setupDrawShaderUniforms(false);
+    setupDrawTextGammaUniforms();
 
     const Rect* clip = &mSnapshot->getLocalClip();
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 8bdc450..1926575 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -105,6 +105,7 @@
 
     ANDROID_API const Rect& getClipBounds();
     ANDROID_API bool quickReject(float left, float top, float right, float bottom);
+    bool quickRejectNoScissor(float left, float top, float right, float bottom);
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
     virtual Rect* getClipRect();
 
@@ -572,6 +573,7 @@
     void setupDrawColor(int color, int alpha);
     void setupDrawColor(float r, float g, float b, float a);
     void setupDrawAlpha8Color(int color, int alpha);
+    void setupDrawTextGamma(const SkPaint* paint);
     void setupDrawShader();
     void setupDrawColorFilter();
     void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
@@ -596,6 +598,7 @@
     void setupDrawExternalTexture(GLuint texture);
     void setupDrawTextureTransform();
     void setupDrawTextureTransformUniforms(mat4& transform);
+    void setupDrawTextGammaUniforms();
     void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
     void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords);
     void setupDrawVertices(GLvoid* vertices);
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index e9c666b..491767f 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -77,6 +77,8 @@
 #define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
 #define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
 
+#define PROGRAM_HAS_GAMMA_CORRECTION 40
+
 ///////////////////////////////////////////////////////////////////////////////
 // Types
 ///////////////////////////////////////////////////////////////////////////////
@@ -146,6 +148,9 @@
     bool isPoint;
     float pointSize;
 
+    bool hasGammaCorrection;
+    float gamma;
+
     /**
      * Resets this description. All fields are reset back to the default
      * values they hold after building a new instance.
@@ -180,6 +185,9 @@
 
         isPoint = false;
         pointSize = 0.0f;
+
+        hasGammaCorrection = false;
+        gamma = 2.2f;
     }
 
     /**
@@ -246,6 +254,7 @@
         if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
         if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
         if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
+        if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
         return key;
     }
 
@@ -261,7 +270,7 @@
     }
 
 private:
-    inline uint32_t getEnumForWrap(GLenum wrap) const {
+    static inline uint32_t getEnumForWrap(GLenum wrap) {
         switch (wrap) {
             case GL_CLAMP_TO_EDGE:
                 return 0;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index a7f1277..fc60279 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -159,6 +159,9 @@
         // PorterDuff
         "uniform vec4 colorBlend;\n"
 };
+const char* gFS_Uniforms_Gamma =
+        "uniform float gamma;\n";
+
 const char* gFS_Main =
         "\nvoid main(void) {\n"
         "    lowp vec4 fragColor;\n";
@@ -184,10 +187,18 @@
         "\nvoid main(void) {\n"
         "    gl_FragColor = texture2D(sampler, outTexCoords);\n"
         "}\n\n";
+const char* gFS_Fast_SingleA8Texture_ApplyGamma =
+        "\nvoid main(void) {\n"
+        "    gl_FragColor = vec4(0.0, 0.0, 0.0, pow(texture2D(sampler, outTexCoords).a, gamma));\n"
+        "}\n\n";
 const char* gFS_Fast_SingleModulateA8Texture =
         "\nvoid main(void) {\n"
         "    gl_FragColor = color * texture2D(sampler, outTexCoords).a;\n"
         "}\n\n";
+const char* gFS_Fast_SingleModulateA8Texture_ApplyGamma =
+        "\nvoid main(void) {\n"
+        "    gl_FragColor = color * pow(texture2D(sampler, outTexCoords).a, gamma);\n"
+        "}\n\n";
 const char* gFS_Fast_SingleGradient =
         "\nvoid main(void) {\n"
         "    gl_FragColor = texture2D(gradientSampler, linear);\n"
@@ -202,6 +213,8 @@
         "    fragColor = color;\n";
 const char* gFS_Main_ModulateColor =
         "    fragColor *= color.a;\n";
+const char* gFS_Main_ModulateColor_ApplyGamma =
+        "    fragColor *= pow(color.a, gamma);\n";
 const char* gFS_Main_AccountForAA =
         "    if (widthProportion < boundaryWidth) {\n"
         "        fragColor *= (widthProportion * inverseBoundaryWidth);\n"
@@ -517,6 +530,9 @@
     if (description.hasBitmap && description.isPoint) {
         shader.append(gFS_Header_Uniforms_PointHasBitmap);
     }
+    if (description.hasGammaCorrection) {
+        shader.append(gFS_Uniforms_Gamma);
+    }
 
     // Optimization for common cases
     if (!description.isAA && !blendFramebuffer &&
@@ -544,9 +560,17 @@
             fast = true;
         } else if (singleA8Texture) {
             if (!description.modulate) {
-                shader.append(gFS_Fast_SingleA8Texture);
+                if (description.hasGammaCorrection) {
+                    shader.append(gFS_Fast_SingleA8Texture_ApplyGamma);
+                } else {
+                    shader.append(gFS_Fast_SingleA8Texture);
+                }
             } else {
-                shader.append(gFS_Fast_SingleModulateA8Texture);
+                if (description.hasGammaCorrection) {
+                    shader.append(gFS_Fast_SingleModulateA8Texture_ApplyGamma);
+                } else {
+                    shader.append(gFS_Fast_SingleModulateA8Texture);
+                }
             }
             fast = true;
         } else if (singleGradient) {
@@ -643,7 +667,11 @@
             }
         }
         if (description.modulate && applyModulate) {
-            shader.append(gFS_Main_ModulateColor);
+            if (description.hasGammaCorrection) {
+                shader.append(gFS_Main_ModulateColor_ApplyGamma);
+            } else {
+                shader.append(gFS_Main_ModulateColor);
+            }
         }
         // Apply the color op if needed
         shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 2255bf2..47b7adf 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -54,7 +54,7 @@
     boolean sendExtraCommand(String provider, String command, inout Bundle extras);
 
     void addProximityAlert(double latitude, double longitude, float distance,
-        long expiration, in PendingIntent intent);
+        long expiration, in PendingIntent intent, in String packageName);
     void removeProximityAlert(in PendingIntent intent);
 
     Bundle getProviderInfo(String provider);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 1299574..ff74f41 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -17,6 +17,7 @@
 package android.location;
 
 import android.app.PendingIntent;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Looper;
@@ -52,7 +53,9 @@
  */
 public class LocationManager {
     private static final String TAG = "LocationManager";
-    private ILocationManager mService;
+
+    private final Context mContext;
+    private final ILocationManager mService;
     private final HashMap<GpsStatus.Listener, GpsStatusListenerTransport> mGpsStatusListeners =
             new HashMap<GpsStatus.Listener, GpsStatusListenerTransport>();
     private final HashMap<GpsStatus.NmeaListener, GpsStatusListenerTransport> mNmeaListeners =
@@ -193,6 +196,7 @@
             }
         }
 
+        @Override
         public void onLocationChanged(Location location) {
             Message msg = Message.obtain();
             msg.what = TYPE_LOCATION_CHANGED;
@@ -200,6 +204,7 @@
             mListenerHandler.sendMessage(msg);
         }
 
+        @Override
         public void onStatusChanged(String provider, int status, Bundle extras) {
             Message msg = Message.obtain();
             msg.what = TYPE_STATUS_CHANGED;
@@ -213,6 +218,7 @@
             mListenerHandler.sendMessage(msg);
         }
 
+        @Override
         public void onProviderEnabled(String provider) {
             Message msg = Message.obtain();
             msg.what = TYPE_PROVIDER_ENABLED;
@@ -220,6 +226,7 @@
             mListenerHandler.sendMessage(msg);
         }
 
+        @Override
         public void onProviderDisabled(String provider) {
             Message msg = Message.obtain();
             msg.what = TYPE_PROVIDER_DISABLED;
@@ -260,8 +267,9 @@
      * right way to create an instance of this class is using the
      * factory Context.getSystemService.
      */
-    public LocationManager(ILocationManager service) {
+    public LocationManager(Context context, ILocationManager service) {
         mService = service;
+        mContext = context;
     }
 
     private LocationProvider createProvider(String name, Bundle info) {
@@ -1086,8 +1094,8 @@
                 ", intent = " + intent);
         }
         try {
-            mService.addProximityAlert(latitude, longitude, radius,
-                                       expiration, intent);
+            mService.addProximityAlert(latitude, longitude, radius, expiration, intent,
+                    mContext.getPackageName());
         } catch (RemoteException ex) {
             Log.e(TAG, "addProximityAlert: RemoteException", ex);
         }
@@ -1361,6 +1369,7 @@
             mNmeaBuffer = new ArrayList<Nmea>();
         }
 
+        @Override
         public void onGpsStarted() {
             if (mListener != null) {
                 Message msg = Message.obtain();
@@ -1369,6 +1378,7 @@
             }
         }
 
+        @Override
         public void onGpsStopped() {
             if (mListener != null) {
                 Message msg = Message.obtain();
@@ -1377,6 +1387,7 @@
             }
         }
 
+        @Override
         public void onFirstFix(int ttff) {
             if (mListener != null) {
                 mGpsStatus.setTimeToFirstFix(ttff);
@@ -1386,6 +1397,7 @@
             }
         }
 
+        @Override
         public void onSvStatusChanged(int svCount, int[] prns, float[] snrs,
                 float[] elevations, float[] azimuths, int ephemerisMask,
                 int almanacMask, int usedInFixMask) {
@@ -1401,6 +1413,7 @@
             }
         }
 
+        @Override
         public void onNmeaReceived(long timestamp, String nmea) {
             if (mNmeaListener != null) {
                 synchronized (mNmeaBuffer) {
diff --git a/location/java/com/android/internal/location/DummyLocationProvider.java b/location/java/com/android/internal/location/DummyLocationProvider.java
index e7b5143..3122960 100644
--- a/location/java/com/android/internal/location/DummyLocationProvider.java
+++ b/location/java/com/android/internal/location/DummyLocationProvider.java
@@ -24,7 +24,7 @@
  * A DummyLocationProvider may be queried to determine the properties
  * of the provider whcih it shadows, but does not actually provide location
  * data.
- * 
+ *
  * {@hide}
  */
 public class DummyLocationProvider extends LocationProvider {
@@ -86,6 +86,7 @@
      * Returns true if the provider requires access to a
      * data network (e.g., the Internet), false otherwise.
      */
+    @Override
     public boolean requiresNetwork() {
         return mRequiresNetwork;
     }
@@ -95,6 +96,7 @@
      * satellite-based positioning system (e.g., GPS), false
      * otherwise.
      */
+    @Override
     public boolean requiresSatellite() {
         return mRequiresSatellite;
     }
@@ -104,6 +106,7 @@
      * cellular network (e.g., to make use of cell tower IDs), false
      * otherwise.
      */
+    @Override
     public boolean requiresCell() {
         return mRequiresCell;
     }
@@ -113,6 +116,7 @@
      * monetary charge to the user, false if use is free.  It is up to
      * each provider to give accurate information.
      */
+    @Override
     public boolean hasMonetaryCost() {
         return mHasMonetaryCost;
     }
@@ -123,6 +127,7 @@
      * under most circumstances but may occassionally not report it
      * should return true.
      */
+    @Override
     public boolean supportsAltitude() {
         return mSupportsAltitude;
     }
@@ -133,6 +138,7 @@
      * under most circumstances but may occassionally not report it
      * should return true.
      */
+    @Override
     public boolean supportsSpeed() {
         return mSupportsSpeed;
     }
@@ -143,6 +149,7 @@
      * under most circumstances but may occassionally not report it
      * should return true.
      */
+    @Override
     public boolean supportsBearing() {
         return mSupportsBearing;
     }
@@ -153,6 +160,7 @@
      * @return the power requirement for this provider, as one of the
      * constants Criteria.POWER_REQUIREMENT_*.
      */
+    @Override
     public int getPowerRequirement() {
         return mPowerRequirement;
     }
@@ -164,6 +172,7 @@
      * @return the horizontal accuracy for this provider, as one of the
      * constants Criteria.ACCURACY_*.
      */
+    @Override
     public int getAccuracy() {
         return mAccuracy;
     }
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 357bf4e..a256079 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -126,6 +126,15 @@
                 sStatic.mDefaultAudio.mNameResId = name;
                 dispatchRouteChanged(sStatic.mDefaultAudio);
             }
+
+            boolean a2dpEnabled;
+            try {
+                a2dpEnabled = mAudioService.isBluetoothA2dpOn();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error querying Bluetooth A2DP state", e);
+                a2dpEnabled = false;
+            }
+
             if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) {
                 mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
                 if (mCurRoutesInfo.mBluetoothName != null) {
@@ -135,13 +144,6 @@
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                         sStatic.mBluetoothA2dpRoute = info;
                         addRoute(sStatic.mBluetoothA2dpRoute);
-                        try {
-                            if (mAudioService.isBluetoothA2dpOn()) {
-                                selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
-                            }
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error selecting Bluetooth A2DP route", e);
-                        }
                     } else {
                         sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName;
                         dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
@@ -151,6 +153,16 @@
                     sStatic.mBluetoothA2dpRoute = null;
                 }
             }
+
+            if (mBluetoothA2dpRoute != null) {
+                if (mCurRoutesInfo.mMainType != AudioRoutesInfo.MAIN_SPEAKER &&
+                        mSelectedRoute == mBluetoothA2dpRoute) {
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudio);
+                } else if (mCurRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
+                        mSelectedRoute == mDefaultAudio && a2dpEnabled) {
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
+                }
+            }
         }
     }
 
diff --git a/packages/SystemUI/res/drawable-hdpi/bugdroid.png b/packages/SystemUI/res/drawable-nodpi/bugdroid.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/bugdroid.png
rename to packages/SystemUI/res/drawable-nodpi/bugdroid.png
Binary files differ
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index c2259132..3e96f9bc 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -613,8 +613,7 @@
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 width, WRAP_CONTENT,
                 st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
-                WindowManager.LayoutParams.FLAG_DITHER
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 st.decorView.mDefaultOpacity);
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 2ef048b..cca9cbb 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2375,16 +2375,6 @@
             if (mNavigationBarOnBottom) {
                 // It's a system nav bar or a portrait screen; nav bar goes on bottom.
                 int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
-                if (mHdmiPlugged) {
-                    // Move the nav bar up if the external display is the same aspect ratio
-                    // but shorter.  This avoids clipping on the external display.
-                    boolean sameAspect = mExternalDisplayHeight > 0 && displayHeight > 0
-                        && ((float) mExternalDisplayWidth / mExternalDisplayHeight > 1)
-                        == ((float) displayWidth / displayHeight > 1);
-                    if (sameAspect && top > mExternalDisplayHeight) {
-                        top = mExternalDisplayHeight;
-                    }
-                }
                 mTmpNavigationFrame.set(0, top, displayWidth, displayHeight);
                 mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
                 if (navVisible) {
@@ -2404,11 +2394,6 @@
             } else {
                 // Landscape screen; nav bar goes to the right.
                 int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
-                if (mHdmiPlugged) {
-                    if (left > mExternalDisplayWidth) {
-                        left = mExternalDisplayWidth;
-                    }
-                }
                 mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
                 mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
                 if (navVisible) {
diff --git a/services/common_time/common_time_server.cpp b/services/common_time/common_time_server.cpp
index 4e5d16e..0125709 100644
--- a/services/common_time/common_time_server.cpp
+++ b/services/common_time/common_time_server.cpp
@@ -487,7 +487,16 @@
             goto bailout;
         }
     } else
-    if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
+    if (ntohl(ipv4_addr->sin_addr.s_addr) == 0xFFFFFFFF) {
+        // If the master election address is the broadcast address, then enable
+        // the broadcast socket option
+        const int one = 1;
+        rc = setsockopt(mSocket, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one));
+        if (rc == -1) {
+            ALOGE("Failed to enable broadcast (errno = %d)", errno);
+            goto bailout;
+        }
+    } else {
         // If the master election address is neither broadcast, nor multicast,
         // then we are misconfigured.  The config API layer should prevent this
         // from ever happening.
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 7725f35..77b3b50 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -836,7 +836,10 @@
             return;
         }
 
-        int bitmapMemoryUsage = views.estimateMemoryUsage();
+        int bitmapMemoryUsage = 0;
+        if (views != null) {
+            bitmapMemoryUsage = views.estimateMemoryUsage();
+        }
         if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
             throw new IllegalArgumentException("RemoteViews for widget update exceeds maximum" +
                     " bitmap memory usage (used: " + bitmapMemoryUsage + ", max: " +
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
new file mode 100644
index 0000000..cc9b9fa
--- /dev/null
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ */
+
+package com.android.server;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothCallback;
+import android.bluetooth.IBluetoothManager;
+import android.bluetooth.IBluetoothManagerCallback;
+import android.bluetooth.IBluetoothStateChangeCallback;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.Log;
+import java.util.List;
+import java.util.ArrayList;
+class BluetoothManagerService extends IBluetoothManager.Stub {
+    private static final String TAG = "BluetoothManagerService";
+    private static final boolean DBG = true;
+
+    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
+    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+    private static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED";
+    private static final String EXTRA_ACTION="action";
+    private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address";
+    private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name";
+    private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
+    private static final int TIMEOUT_SAVE_MS = 500; //Maximum msec to wait for a save
+
+    private static final int MESSAGE_ENABLE = 1;
+    private static final int MESSAGE_DISABLE = 2;
+    private static final int MESSAGE_REGISTER_ADAPTER = 20;
+    private static final int MESSAGE_UNREGISTER_ADAPTER = 21;
+    private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30;
+    private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
+    private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
+    private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
+    private static final int MESSAGE_BLUETOOTH_STATE_CHANGE=60;
+    private static final int MESSAGE_TIMEOUT_BIND =100;
+    private static final int MESSAGE_TIMEOUT_UNBIND =101;
+    private static final int MESSAGE_GET_NAME_AND_ADDRESS=200;
+    private static final int MESSAGE_SAVE_NAME_AND_ADDRESS=201;
+    private static final int MAX_SAVE_RETRIES=3;
+
+    private final Context mContext;
+
+    // Locks are not provided for mName and mAddress.
+    // They are accessed in handler or broadcast receiver, same thread context.
+    private String mAddress;
+    private String mName;
+    private final ContentResolver mContentResolver;
+    private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
+    private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
+    private IBluetooth mBluetooth;
+    private boolean mBinding;
+    private boolean mUnbinding;
+
+    private void registerForAirplaneMode(IntentFilter filter) {
+        final ContentResolver resolver = mContext.getContentResolver();
+        final String airplaneModeRadios = Settings.System.getString(resolver,
+                Settings.System.AIRPLANE_MODE_RADIOS);
+        final String toggleableRadios = Settings.System.getString(resolver,
+                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+        boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true :
+                airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
+        if (mIsAirplaneSensitive) {
+            filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+        }
+    }
+
+    private final IBluetoothCallback mBluetoothCallback =  new IBluetoothCallback.Stub() {
+        @Override
+        public void onBluetoothStateChange(int prevState, int newState) throws RemoteException  {
+            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
+            mHandler.sendMessage(msg);
+        }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
+                String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
+                if (DBG) Log.d(TAG, "Bluetooth Adapter name changed to " + newName);
+                if (newName != null) {
+                    storeNameAndAddress(newName, null);
+                }
+            } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
+                if (isAirplaneModeOn()) {
+                        // disable without persisting the setting
+                        handleDisable(false);
+                } else {
+                    if (isBluetoothPersistedStateOn()) {
+                        // enable without persisting the setting
+                        handleEnable(false);
+                    }
+                }
+            }
+        }
+    };
+
+    BluetoothManagerService(Context context) {
+        mContext = context;
+        mBluetooth = null;
+        mBinding = false;
+        mUnbinding = false;
+        mAddress = null;
+        mName = null;
+        mContentResolver = context.getContentResolver();
+        mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
+        mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
+        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        registerForAirplaneMode(filter);
+        mContext.registerReceiver(mReceiver, filter);
+        boolean airplaneModeOn = isAirplaneModeOn();
+        boolean bluetoothOn = isBluetoothPersistedStateOn();
+        loadStoredNameAndAddress();
+        if (DBG) Log.d(TAG, "airplaneModeOn: " + airplaneModeOn + " bluetoothOn: " + bluetoothOn);
+        if (bluetoothOn) {
+            //Enable
+            if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
+            enable();
+        } else if (!isNameAndAddressSet()) {
+            //Sync the Bluetooth name and address from the Bluetooth Adapter
+            if (DBG) Log.d(TAG,"Retrieving Bluetooth Adapter name and address...");
+            getNameAndAddress();
+        }
+    }
+
+    /**
+     *  Returns true if airplane mode is currently on
+     */
+    private final boolean isAirplaneModeOn() {
+        return Settings.System.getInt(mContext.getContentResolver(),
+                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+    }
+
+    /**
+     *  Returns true if the Bluetooth saved state is "on"
+     */
+    private final boolean isBluetoothPersistedStateOn() {
+        return Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.BLUETOOTH_ON, 0) ==1;
+    }
+
+    /**
+     *  Save the Bluetooth on/off state
+     *
+     */
+    private void persistBluetoothSetting(boolean setOn) {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                               Settings.Secure.BLUETOOTH_ON,
+                               setOn ? 1 : 0);
+    }
+
+    /**
+     * Returns true if the Bluetooth Adapter's name and address is
+     * locally cached
+     * @return
+     */
+    private boolean isNameAndAddressSet() {
+        return mName !=null && mAddress!= null && mName.length()>0 && mAddress.length()>0;
+    }
+
+    /**
+     * Retrieve the Bluetooth Adapter's name and address and save it in
+     * in the local cache
+     */
+    private void loadStoredNameAndAddress() {
+        if (DBG) Log.d(TAG, "Loading stored name and address");
+        mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
+        mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
+        if (mName == null || mAddress == null) {
+            if (DBG) Log.d(TAG, "Name or address not cached...");
+        }
+    }
+
+    /**
+     * Save the Bluetooth name and address in the persistent store.
+     * Only non-null values will be saved.
+     * @param name
+     * @param address
+     */
+    private void storeNameAndAddress(String name, String address) {
+        if (name != null) {
+            Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name);
+            mName = name;
+            if (DBG) Log.d(TAG,"Stored Bluetooth name: " +
+                Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_NAME));
+        }
+
+        if (address != null) {
+            Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address);
+            mAddress=address;
+            if (DBG)  Log.d(TAG,"Stored Bluetoothaddress: " +
+                Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS));
+        }
+    }
+
+    public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
+        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER);
+        msg.obj = callback;
+        mHandler.sendMessage(msg);
+        synchronized(mConnection) {
+            return mBluetooth;
+        }
+    }
+
+    public void unregisterAdapter(IBluetoothManagerCallback callback) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
+        Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER);
+        msg.obj = callback;
+        mHandler.sendMessage(msg);
+    }
+
+    public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
+        Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK);
+        msg.obj = callback;
+        mHandler.sendMessage(msg);
+    }
+
+    public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM,
+                                                "Need BLUETOOTH permission");
+        Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK);
+        msg.obj = callback;
+        mHandler.sendMessage(msg);
+    }
+
+    public boolean isEnabled() {
+        synchronized(mConnection) {
+            try {
+                return (mBluetooth != null && mBluetooth.isEnabled());
+            } catch (RemoteException e) {
+                Log.e(TAG, "isEnabled()", e);
+            }
+        }
+        return false;
+    }
+
+    public void getNameAndAddress() {
+        if (DBG) {
+            Log.d(TAG,"getNameAndAddress(): mBluetooth = " + mBluetooth +
+                  " mBinding = " + mBinding);
+        }
+        synchronized(mConnection) {
+            if (mBinding) return;
+            if (mConnection == null) mBinding = true;
+        }
+        Message msg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+        mHandler.sendMessage(msg);
+    }
+
+    public boolean enable() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                                "Need BLUETOOTH ADMIN permission");
+        if (DBG) {
+            Log.d(TAG,"enable():  mBluetooth =" + mBluetooth +
+                    " mBinding = " + mBinding);
+        }
+
+        synchronized(mConnection) {
+            if (mBinding) {
+                Log.w(TAG,"enable(): binding in progress. Returning..");
+                return true;
+            }
+            if (mConnection == null) mBinding = true;
+        }
+
+        Message msg = mHandler.obtainMessage(MESSAGE_ENABLE);
+        msg.arg1=1; //persist
+        mHandler.sendMessage(msg);
+        return true;
+    }
+
+    public boolean disable(boolean persist) {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                                "Need BLUETOOTH ADMIN permissicacheNameAndAddresson");
+        if (DBG) {
+            Log.d(TAG,"disable(): mBluetooth = " + mBluetooth +
+                " mBinding = " + mBinding);
+        }
+
+        synchronized(mConnection) {
+             if (mBluetooth == null) return false;
+        }
+        Message msg = mHandler.obtainMessage(MESSAGE_DISABLE);
+        msg.arg1=(persist?1:0);
+        mHandler.sendMessage(msg);
+        return true;
+    }
+
+    public void unbindAndFinish() {
+        if (DBG) {
+            Log.d(TAG,"unbindAndFinish(): " + mBluetooth +
+                " mBinding = " + mBinding);
+        }
+
+        synchronized (mConnection) {
+            if (mUnbinding) return;
+            mUnbinding = true;
+            if (mConnection != null) {
+                if (!mConnection.isGetNameAddressOnly()) {
+                    //Unregister callback object
+                    try {
+                        mBluetooth.unregisterCallback(mBluetoothCallback);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Unable to register BluetoothCallback",re);
+                    }
+                }
+                if (DBG) Log.d(TAG, "Sending unbind request.");
+                mBluetooth = null;
+                //Unbind
+                mContext.unbindService(mConnection);
+                mUnbinding = false;
+            } else {
+                mUnbinding=false;
+            }
+        }
+    }
+
+    private void sendBluetoothStateCallback(boolean isUp) {
+        int n = mStateChangeCallbacks.beginBroadcast();
+        if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
+        for (int i=0; i <n;i++) {
+            try {
+                mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
+            }
+        }
+        mStateChangeCallbacks.finishBroadcast();
+    }
+
+    /**
+     * Inform BluetoothAdapter instances that Adapter service is down
+     */
+    private void sendBluetoothServiceDownCallback() {
+        if (!mConnection.isGetNameAddressOnly()) {
+            if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
+            int n = mCallbacks.beginBroadcast();
+            Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
+            for (int i=0; i <n;i++) {
+                try {
+                    mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
+                }  catch (RemoteException e) {
+                    Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
+                }
+            }
+            mCallbacks.finishBroadcast();
+        }
+    }
+    public String getAddress() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                                "Need BLUETOOTH ADMIN permission");
+        synchronized(mConnection) {
+            if (mBluetooth != null) {
+                try {
+                    return mBluetooth.getAddress();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "getAddress(): Unable to retrieve address remotely..Returning cached address",e);
+                }
+            }
+        }
+        // mAddress is accessed from outside.
+        // It is alright without a lock. Here, bluetooth is off, no other thread is
+        // changing mAddress
+        return mAddress;
+    }
+
+    public String getName() {
+        mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                                "Need BLUETOOTH ADMIN permission");
+        synchronized(mConnection) {
+            if (mBluetooth != null) {
+                try {
+                    return mBluetooth.getName();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "getName(): Unable to retrieve name remotely..Returning cached name",e);
+                }
+            }
+        }
+        // mName is accessed from outside.
+        // It alright without a lock. Here, bluetooth is off, no other thread is
+        // changing mName
+        return mName;
+    }
+
+    private class BluetoothServiceConnection implements ServiceConnection {
+
+        private boolean mGetNameAddressOnly;
+
+        public void setGetNameAddressOnly(boolean getOnly) {
+            mGetNameAddressOnly = getOnly;
+        }
+
+        public boolean isGetNameAddressOnly() {
+            return mGetNameAddressOnly;
+        }
+
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "BluetoothServiceConnection: connected to AdapterService");
+            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
+            msg.obj = service;
+            mHandler.sendMessage(msg);
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            // Called if we unexpected disconnected.
+            if (DBG) Log.d(TAG, "BluetoothServiceConnection: disconnected from AdapterService");
+            Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (DBG) Log.d (TAG, "Message: " + msg.what);
+            switch (msg.what) {
+                case MESSAGE_GET_NAME_AND_ADDRESS: {
+                    if (DBG) Log.d(TAG,"MESSAGE_GET_NAME_AND_ADDRESS");
+                    synchronized(mConnection) {
+                        //Start bind request
+                        if (mBluetooth == null) {
+                            if (DBG) Log.d(TAG, "Binding to service to get name and address");
+                            mConnection.setGetNameAddressOnly(true);
+                            //Start bind timeout and bind
+                            Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
+                            mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
+                            Intent i = new Intent(IBluetooth.class.getName());
+                            if (!mContext.bindService(i, mConnection,
+                                                  Context.BIND_AUTO_CREATE)) {
+                                mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+                                Log.e(TAG, "fail to bind to: " + IBluetooth.class.getName());
+                            }
+                        }
+                        else {
+                            Message saveMsg= mHandler.obtainMessage(MESSAGE_SAVE_NAME_AND_ADDRESS);
+                            mHandler.sendMessage(saveMsg);
+                        }
+                    }
+                    break;
+                }
+                case MESSAGE_SAVE_NAME_AND_ADDRESS: {
+                    if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
+                    synchronized(mConnection) {
+                        if (mBluetooth != null) {
+                            String name =  null;
+                            String address = null;
+                            try {
+                                name =  mBluetooth.getName();
+                                address = mBluetooth.getAddress();
+                            } catch (RemoteException re) {
+                                Log.e(TAG,"",re);
+                            }
+
+                            if (name != null && address != null) {
+                                storeNameAndAddress(name,address);
+                                sendBluetoothServiceDownCallback();
+                                unbindAndFinish();
+                            } else {
+                                if (msg.arg1 < MAX_SAVE_RETRIES) {
+                                    Message retryMsg = mHandler.obtainMessage(MESSAGE_SAVE_NAME_AND_ADDRESS);
+                                    retryMsg.arg1= 1+msg.arg1;
+                                    if (DBG) Log.d(TAG,"Retrying name/address remote retrieval and save.....Retry count =" + retryMsg.arg1);
+                                    mHandler.sendMessageDelayed(retryMsg, TIMEOUT_SAVE_MS);
+                                } else {
+                                    Log.w(TAG,"Maximum name/address remote retrieval retry exceeded");
+                                    sendBluetoothServiceDownCallback();
+                                    unbindAndFinish();
+                                }
+                            }
+                        }
+                    }
+                    break;
+                }
+                case MESSAGE_ENABLE:
+                    if (DBG) {
+                        Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
+                    }
+
+                    handleEnable(msg.arg1 == 1);
+                    break;
+
+                case MESSAGE_DISABLE:
+                    handleDisable(msg.arg1 == 1);
+                    break;
+
+                case MESSAGE_REGISTER_ADAPTER:
+                {
+                    IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
+                    boolean added = mCallbacks.register(callback);
+                    Log.d(TAG,"Added callback: " +  (callback == null? "null": callback)  +":" +added );
+                }
+                    break;
+                case MESSAGE_UNREGISTER_ADAPTER:
+                {
+                    IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj;
+                    boolean removed = mCallbacks.unregister(callback);
+                    Log.d(TAG,"Removed callback: " +  (callback == null? "null": callback)  +":" + removed);
+                    break;
+                }
+                case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
+                {
+                    IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
+                    mStateChangeCallbacks.register(callback);
+                    break;
+                }
+                case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK:
+                {
+                    IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
+                    mStateChangeCallbacks.unregister(callback);
+                    break;
+                }
+                case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
+                {
+                    if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED");
+
+                    //Remove timeout
+                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+
+                    IBinder service = (IBinder) msg.obj;
+                    synchronized(mConnection) {
+                        mBinding = false;
+                        mBluetooth = IBluetooth.Stub.asInterface(service);
+
+                        if (mConnection.isGetNameAddressOnly()) {
+                            //Request GET NAME AND ADDRESS
+                            Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+                            mHandler.sendMessage(getMsg);
+                            return;
+                        }
+
+                        //Register callback object
+                        try {
+                            mBluetooth.registerCallback(mBluetoothCallback);
+                        } catch (RemoteException re) {
+                            Log.e(TAG, "Unable to register BluetoothCallback",re);
+                        }
+
+                        //Inform BluetoothAdapter instances that service is up
+                        int n = mCallbacks.beginBroadcast();
+                        Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
+                        for (int i=0; i <n;i++) {
+                            try {
+                                mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
+                            }
+                        }
+                        mCallbacks.finishBroadcast();
+
+                        //Do enable request
+                        try {
+                            if(!mBluetooth.enable()) {
+                                Log.e(TAG,"IBluetooth.enable() returned false");
+                            }
+                        } catch (RemoteException e) {
+                            Log.e(TAG,"Unable to call enable()",e);
+                        }
+                    }
+
+                    break;
+                }
+                case MESSAGE_TIMEOUT_BIND: {
+                    Log.e(TAG, "MESSAGE_TIMEOUT_BIND");
+                    synchronized(mConnection) {
+                        mBinding = false;
+                    }
+                    break;
+                }
+                case MESSAGE_BLUETOOTH_STATE_CHANGE:
+                {
+                    int prevState = msg.arg1;
+                    int newState = msg.arg2;
+                    if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = " + prevState + ", newState=" + newState);
+                    if (prevState != newState) {
+                        //Notify all proxy objects first of adapter state change
+                        if (newState == BluetoothAdapter.STATE_ON || newState == BluetoothAdapter.STATE_OFF) {
+                            boolean isUp = (newState==BluetoothAdapter.STATE_ON);
+                            sendBluetoothStateCallback(isUp);
+
+                            //If Bluetooth is off, send service down event to proxy objects, and unbind
+                            if (!isUp) {
+                                sendBluetoothServiceDownCallback();
+                                unbindAndFinish();
+                            }
+                        }
+
+                        //Send broadcast message to everyone else
+                        Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+                        intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
+                        intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
+                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+                        if (DBG) Log.d(TAG,"Bluetooth State Change Intent: " + prevState + " -> " + newState);
+                        mContext.sendBroadcast(intent,BLUETOOTH_PERM);
+                    }
+                    break;
+                }
+                case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
+                {
+                    if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED");
+                    sendBluetoothServiceDownCallback();
+                    break;
+                }
+                case MESSAGE_TIMEOUT_UNBIND:
+                {
+                    Log.e(TAG, "MESSAGE_TIMEOUT_UNBIND");
+                    synchronized(mConnection) {
+                        mUnbinding = false;
+                    }
+                    break;
+                }
+            }
+        }
+    };
+
+    private void handleEnable(boolean persist) {
+        if (persist) {
+            persistBluetoothSetting(true);
+        }
+
+        synchronized(mConnection) {
+            if (mBluetooth == null) {
+                //Start bind timeout and bind
+                Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
+                mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
+                mConnection.setGetNameAddressOnly(false);
+                Intent i = new Intent(IBluetooth.class.getName());
+                if (!mContext.bindService(i, mConnection,Context.BIND_AUTO_CREATE)) {
+                    mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+                    Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());
+                }
+            } else {
+                //Check if name and address is loaded if not get it first.
+                if (!isNameAndAddressSet()) {
+                    try {
+                        if (DBG) Log.d(TAG,"Getting and storing Bluetooth name and address prior to enable.");
+                        storeNameAndAddress(mBluetooth.getName(),mBluetooth.getAddress());
+                    } catch (RemoteException e) {Log.e(TAG, "", e);};
+                }
+
+                //Enable bluetooth
+                try {
+                    if(!mBluetooth.enable()) {
+                        Log.e(TAG,"IBluetooth.enable() returned false");
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG,"Unable to call enable()",e);
+                }
+            }
+        }
+    }
+
+    private void handleDisable(boolean persist) {
+        synchronized(mConnection) {
+            if (mBluetooth != null ) {
+                if (persist) {
+                    persistBluetoothSetting(false);
+                }
+                mConnection.setGetNameAddressOnly(false);
+                if (DBG) Log.d(TAG,"Sending off request.");
+
+                try {
+                    if(!mBluetooth.disable()) {
+                        Log.e(TAG,"IBluetooth.disable() returned false");
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG,"Unable to call disable()",e);
+                }
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java
index 9a25d2e..c316733 100644
--- a/services/java/com/android/server/CommonTimeManagementService.java
+++ b/services/java/com/android/server/CommonTimeManagementService.java
@@ -120,6 +120,8 @@
             reevaluateServiceState();
         }
         public void limitReached(String limitName, String iface) { }
+
+        public void interfaceClassDataActivityChanged(String label, boolean active) {}
     };
 
     private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 230f07b..9f93901 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
+import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
 import static android.net.ConnectivityManager.isNetworkTypeValid;
@@ -35,6 +36,7 @@
 import android.net.DummyDataStateTracker;
 import android.net.EthernetDataTracker;
 import android.net.IConnectivityManager;
+import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
 import android.net.INetworkStatsService;
@@ -546,6 +548,13 @@
         mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
         mSettingsObserver.observe(mContext);
 
+        INetworkManagementEventObserver netdObserver = new NetdObserver();
+        try {
+            mNetd.registerObserver(netdObserver);
+        } catch (RemoteException e) {
+            loge("Error registering observer :" + e);
+        }
+
         loadGlobalProxy();
     }
 private NetworkStateTracker makeWimaxStateTracker() {
@@ -923,6 +932,19 @@
         return tracker != null && tracker.setRadio(turnOn);
     }
 
+    private class NetdObserver extends INetworkManagementEventObserver.Stub {
+        public void interfaceClassDataActivityChanged(String label, boolean active) {
+            int deviceType = Integer.parseInt(label);
+            sendDataActivityBroadcast(deviceType, active);
+        }
+
+        public void interfaceStatusChanged(String iface, boolean up) {}
+        public void interfaceLinkStateChanged(String iface, boolean up) {}
+        public void interfaceAdded(String iface) {}
+        public void interfaceRemoved(String iface) {}
+        public void limitReached(String limitName, String iface) {}
+    }
+
     /**
      * Used to notice when the calling process dies so we can self-expire
      *
@@ -1759,6 +1781,13 @@
         sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
     }
 
+    private void sendDataActivityBroadcast(int deviceType, boolean active) {
+        Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
+        intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
+        intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
+        mContext.sendOrderedBroadcast(intent, RECEIVE_DATA_ACTIVITY_CHANGE);
+    }
+
     /**
      * Called when an attempt to fail over to another network has failed.
      * @param info the {@link NetworkInfo} for the failed network
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 72c0767..e7dac72 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -32,7 +32,6 @@
 import android.os.SystemClock;
 import android.os.UEventObserver;
 import android.provider.Settings;
-import android.server.BluetoothService;
 import android.util.Log;
 import android.util.Slog;
 
@@ -150,7 +149,8 @@
                         intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
 
                         // Check if this is Bluetooth Dock
-                        String address = BluetoothService.readDockBluetoothAddress();
+                        // TODO(BT): Get Dock address.
+                        String address = null;
                         if (address != null)
                             intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
                                     BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 2918dbc..06b056d 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -19,18 +19,13 @@
 import android.app.Activity;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.ContentQueryMap;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.location.Address;
@@ -46,7 +41,6 @@
 import android.location.LocationProvider;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
-import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -58,14 +52,15 @@
 import android.os.RemoteException;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.provider.Settings.NameValueTable;
 import android.util.Log;
 import android.util.Slog;
 import android.util.PrintWriterPrinter;
 
 import com.android.internal.content.PackageMonitor;
-import com.android.internal.location.GpsNetInitiatedHandler;
 
 import com.android.server.location.GeocoderProxy;
+import com.android.server.location.GeofenceManager;
 import com.android.server.location.GpsLocationProvider;
 import com.android.server.location.LocationProviderInterface;
 import com.android.server.location.LocationProviderProxy;
@@ -95,9 +90,6 @@
     private static final String TAG = "LocationManagerService";
     private static final boolean LOCAL_LOGV = false;
 
-    // The last time a location was written, by provider name.
-    private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>();
-
     private static final String ACCESS_FINE_LOCATION =
         android.Manifest.permission.ACCESS_FINE_LOCATION;
     private static final String ACCESS_COARSE_LOCATION =
@@ -147,7 +139,7 @@
     private final static String WAKELOCK_KEY = "LocationManagerService";
     private PowerManager.WakeLock mWakeLock = null;
     private int mPendingBroadcasts;
-    
+
     /**
      * List of all receivers.
      */
@@ -179,13 +171,7 @@
      */
     private final WorkSource mTmpWorkSource = new WorkSource();
 
-    // Proximity listeners
-    private Receiver mProximityReceiver = null;
-    private ILocationListener mProximityListener = null;
-    private HashMap<PendingIntent,ProximityAlert> mProximityAlerts =
-        new HashMap<PendingIntent,ProximityAlert>();
-    private HashSet<ProximityAlert> mProximitiesEntered =
-        new HashSet<ProximityAlert>();
+    GeofenceManager mGeofenceManager;
 
     // Last known location for each provider
     private HashMap<String,Location> mLastKnownLocation =
@@ -266,13 +252,6 @@
             throw new IllegalStateException("Request for non-existent listener");
         }
 
-        public PendingIntent getPendingIntent() {
-            if (mPendingIntent != null) {
-                return mPendingIntent;
-            }
-            throw new IllegalStateException("Request for non-existent intent");
-        }
-
         public boolean callStatusChangedLocked(String provider, int status, Bundle extras) {
             if (mListener != null) {
                 try {
@@ -280,11 +259,9 @@
                         // synchronize to ensure incrementPendingBroadcastsLocked()
                         // is called before decrementPendingBroadcasts()
                         mListener.onStatusChanged(provider, status, extras);
-                        if (mListener != mProximityListener) {
-                            // call this after broadcasting so we do not increment
-                            // if we throw an exeption.
-                            incrementPendingBroadcastsLocked();
-                        }
+                        // call this after broadcasting so we do not increment
+                        // if we throw an exeption.
+                        incrementPendingBroadcastsLocked();
                     }
                 } catch (RemoteException e) {
                     return false;
@@ -317,11 +294,9 @@
                         // synchronize to ensure incrementPendingBroadcastsLocked()
                         // is called before decrementPendingBroadcasts()
                         mListener.onLocationChanged(location);
-                        if (mListener != mProximityListener) {
-                            // call this after broadcasting so we do not increment
-                            // if we throw an exeption.
-                            incrementPendingBroadcastsLocked();
-                        }
+                        // call this after broadcasting so we do not increment
+                        // if we throw an exeption.
+                        incrementPendingBroadcastsLocked();
                     }
                 } catch (RemoteException e) {
                     return false;
@@ -357,11 +332,9 @@
                         } else {
                             mListener.onProviderDisabled(provider);
                         }
-                        if (mListener != mProximityListener) {
-                            // call this after broadcasting so we do not increment
-                            // if we throw an exeption.
-                            incrementPendingBroadcastsLocked();
-                        }
+                        // call this after broadcasting so we do not increment
+                        // if we throw an exeption.
+                        incrementPendingBroadcastsLocked();
                     }
                 } catch (RemoteException e) {
                     return false;
@@ -402,6 +375,7 @@
             }
         }
 
+        @Override
         public void onSendFinished(PendingIntent pendingIntent, Intent intent,
                 int resultCode, String resultData, Bundle resultExtras) {
             synchronized (this) {
@@ -424,6 +398,7 @@
         }
     }
 
+    @Override
     public void locationCallbackFinished(ILocationListener listener) {
         //Do not use getReceiver here as that will add the ILocationListener to
         //the receiver list if it is not found.  If it is not found then the
@@ -442,6 +417,7 @@
     }
 
     private final class SettingsObserver implements Observer {
+        @Override
         public void update(Observable o, Object arg) {
             synchronized (mLock) {
                 updateProvidersLocked();
@@ -588,7 +564,7 @@
     }
 
     void systemReady() {
-        // we defer starting up the service until the system is ready 
+        // we defer starting up the service until the system is ready
         Thread thread = new Thread(null, this, "LocationManagerService");
         thread.start();
     }
@@ -616,20 +592,22 @@
         // listen for settings changes
         ContentResolver resolver = mContext.getContentResolver();
         Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null,
-                "(" + Settings.System.NAME + "=?)",
+                "(" + NameValueTable.NAME + "=?)",
                 new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED},
                 null);
-        mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler);
+        mSettings = new ContentQueryMap(settingsCursor, NameValueTable.NAME, true, mLocationHandler);
         SettingsObserver settingsObserver = new SettingsObserver();
         mSettings.addObserver(settingsObserver);
     }
 
+    @Override
     public void run()
     {
         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
         Looper.prepare();
         mLocationHandler = new LocationWorkerHandler();
         initialize();
+        mGeofenceManager = new GeofenceManager(mContext);
         Looper.loop();
     }
 
@@ -690,6 +668,7 @@
         return true;
     }
 
+    @Override
     public List<String> getAllProviders() {
         try {
             synchronized (mLock) {
@@ -715,6 +694,7 @@
         return out;
     }
 
+    @Override
     public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
         try {
             synchronized (mLock) {
@@ -782,6 +762,7 @@
     }
 
     private class LpPowerComparator implements Comparator<LocationProviderInterface> {
+        @Override
         public int compare(LocationProviderInterface l1, LocationProviderInterface l2) {
             // Smaller is better
             return (l1.getPowerRequirement() - l2.getPowerRequirement());
@@ -793,6 +774,7 @@
     }
 
     private class LpAccuracyComparator implements Comparator<LocationProviderInterface> {
+        @Override
         public int compare(LocationProviderInterface l1, LocationProviderInterface l2) {
             // Smaller is better
             return (l1.getAccuracy() - l2.getAccuracy());
@@ -815,6 +797,7 @@
                 (p.supportsSpeed() ? SPEED_SCORE : 0);
         }
 
+        @Override
         public int compare(LocationProviderInterface l1, LocationProviderInterface l2) {
             return (score(l2) - score(l1)); // Bigger is better
          }
@@ -896,6 +879,7 @@
      * @param enabledOnly if true then only a provider that is currently enabled is returned
      * @return name of the provider that best matches the requirements
      */
+    @Override
     public String getBestProvider(Criteria criteria, boolean enabledOnly) {
         List<String> goodProviders = getProviders(criteria, enabledOnly);
         if (!goodProviders.isEmpty()) {
@@ -951,6 +935,7 @@
         return null;
     }
 
+    @Override
     public boolean providerMeetsCriteria(String provider, Criteria criteria) {
         LocationProviderInterface p = mProvidersByName.get(provider);
         if (p == null) {
@@ -988,7 +973,7 @@
         }
 
         ArrayList<Receiver> deadReceivers = null;
-        
+
         ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
         if (records != null) {
             final int N = records.size();
@@ -1010,7 +995,7 @@
                 removeUpdatesLocked(deadReceivers.get(i));
             }
         }
-        
+
         if (enabled) {
             p.enable();
             if (listeners > 0) {
@@ -1148,14 +1133,10 @@
                 }
            }
         }
-        for (ProximityAlert alert : mProximityAlerts.values()) {
-            if (alert.mUid == uid) {
-                return true;
-            }
-        }
         return false;
     }
 
+    @Override
     public void requestLocationUpdates(String provider, Criteria criteria,
         long minTime, float minDistance, boolean singleShot, ILocationListener listener) {
         if (criteria != null) {
@@ -1181,6 +1162,20 @@
         }
     }
 
+    void validatePackageName(int uid, String packageName) {
+        if (packageName == null) {
+            throw new SecurityException("packageName cannot be null");
+        }
+        String[] packages = mPackageManager.getPackagesForUid(uid);
+        if (packages == null) {
+            throw new SecurityException("invalid UID " + uid);
+        }
+        for (String pkg : packages) {
+            if (packageName.equals(pkg)) return;
+        }
+        throw new SecurityException("invalid package name");
+    }
+
     void validatePendingIntent(PendingIntent intent) {
         if (intent.isTargetedToPackage()) {
             return;
@@ -1193,6 +1188,7 @@
         //        + intent);
     }
 
+    @Override
     public void requestLocationUpdatesPI(String provider, Criteria criteria,
             long minTime, float minDistance, boolean singleShot, PendingIntent intent) {
         validatePendingIntent(intent);
@@ -1270,6 +1266,7 @@
         }
     }
 
+    @Override
     public void removeUpdates(ILocationListener listener) {
         try {
             synchronized (mLock) {
@@ -1284,6 +1281,7 @@
         }
     }
 
+    @Override
     public void removeUpdatesPI(PendingIntent intent) {
         try {
             synchronized (mLock) {
@@ -1370,6 +1368,7 @@
         }
     }
 
+    @Override
     public boolean addGpsStatusListener(IGpsStatusListener listener) {
         if (mGpsStatusProvider == null) {
             return false;
@@ -1388,6 +1387,7 @@
         return true;
     }
 
+    @Override
     public void removeGpsStatusListener(IGpsStatusListener listener) {
         synchronized (mLock) {
             try {
@@ -1398,6 +1398,7 @@
         }
     }
 
+    @Override
     public boolean sendExtraCommand(String provider, String command, Bundle extras) {
         if (provider == null) {
             // throw NullPointerException to remain compatible with previous implementation
@@ -1417,11 +1418,12 @@
             if (p == null) {
                 return false;
             }
-    
+
             return p.sendExtraCommand(command, extras);
         }
     }
 
+    @Override
     public boolean sendNiResponse(int notifId, int userResponse)
     {
         if (Binder.getCallingUid() != Process.myUid()) {
@@ -1438,223 +1440,11 @@
         }
     }
 
-    class ProximityAlert {
-        final int  mUid;
-        final double mLatitude;
-        final double mLongitude;
-        final float mRadius;
-        final long mExpiration;
-        final PendingIntent mIntent;
-        final Location mLocation;
-
-        public ProximityAlert(int uid, double latitude, double longitude,
-            float radius, long expiration, PendingIntent intent) {
-            mUid = uid;
-            mLatitude = latitude;
-            mLongitude = longitude;
-            mRadius = radius;
-            mExpiration = expiration;
-            mIntent = intent;
-
-            mLocation = new Location("");
-            mLocation.setLatitude(latitude);
-            mLocation.setLongitude(longitude);
-        }
-
-        long getExpiration() {
-            return mExpiration;
-        }
-
-        PendingIntent getIntent() {
-            return mIntent;
-        }
-
-        boolean isInProximity(double latitude, double longitude, float accuracy) {
-            Location loc = new Location("");
-            loc.setLatitude(latitude);
-            loc.setLongitude(longitude);
-
-            double radius = loc.distanceTo(mLocation);
-            return radius <= Math.max(mRadius,accuracy);
-        }
-        
-        @Override
-        public String toString() {
-            return "ProximityAlert{"
-                    + Integer.toHexString(System.identityHashCode(this))
-                    + " uid " + mUid + mIntent + "}";
-        }
-        
-        void dump(PrintWriter pw, String prefix) {
-            pw.println(prefix + this);
-            pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude);
-            pw.println(prefix + "mRadius=" + mRadius + " mExpiration=" + mExpiration);
-            pw.println(prefix + "mIntent=" + mIntent);
-            pw.println(prefix + "mLocation:");
-            mLocation.dump(new PrintWriterPrinter(pw), prefix + "  ");
-        }
-    }
-
-    // Listener for receiving locations to trigger proximity alerts
-    class ProximityListener extends ILocationListener.Stub implements PendingIntent.OnFinished {
-
-        boolean isGpsAvailable = false;
-
-        // Note: this is called with the lock held.
-        public void onLocationChanged(Location loc) {
-
-            // If Gps is available, then ignore updates from NetworkLocationProvider
-            if (loc.getProvider().equals(LocationManager.GPS_PROVIDER)) {
-                isGpsAvailable = true;
-            }
-            if (isGpsAvailable && loc.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
-                return;
-            }
-
-            // Process proximity alerts
-            long now = System.currentTimeMillis();
-            double latitude = loc.getLatitude();
-            double longitude = loc.getLongitude();
-            float accuracy = loc.getAccuracy();
-            ArrayList<PendingIntent> intentsToRemove = null;
-
-            for (ProximityAlert alert : mProximityAlerts.values()) {
-                PendingIntent intent = alert.getIntent();
-                long expiration = alert.getExpiration();
-
-                if ((expiration == -1) || (now <= expiration)) {
-                    boolean entered = mProximitiesEntered.contains(alert);
-                    boolean inProximity =
-                        alert.isInProximity(latitude, longitude, accuracy);
-                    if (!entered && inProximity) {
-                        if (LOCAL_LOGV) {
-                            Slog.v(TAG, "Entered alert");
-                        }
-                        mProximitiesEntered.add(alert);
-                        Intent enteredIntent = new Intent();
-                        enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true);
-                        try {
-                            synchronized (this) {
-                                // synchronize to ensure incrementPendingBroadcasts()
-                                // is called before decrementPendingBroadcasts()
-                                intent.send(mContext, 0, enteredIntent, this, mLocationHandler,
-                                        ACCESS_FINE_LOCATION);
-                                // call this after broadcasting so we do not increment
-                                // if we throw an exeption.
-                                incrementPendingBroadcasts();
-                            }
-                        } catch (PendingIntent.CanceledException e) {
-                            if (LOCAL_LOGV) {
-                                Slog.v(TAG, "Canceled proximity alert: " + alert, e);
-                            }
-                            if (intentsToRemove == null) {
-                                intentsToRemove = new ArrayList<PendingIntent>();
-                            }
-                            intentsToRemove.add(intent);
-                        }
-                    } else if (entered && !inProximity) {
-                        if (LOCAL_LOGV) {
-                            Slog.v(TAG, "Exited alert");
-                        }
-                        mProximitiesEntered.remove(alert);
-                        Intent exitedIntent = new Intent();
-                        exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);
-                        try {
-                            synchronized (this) {
-                                // synchronize to ensure incrementPendingBroadcasts()
-                                // is called before decrementPendingBroadcasts()
-                                intent.send(mContext, 0, exitedIntent, this, mLocationHandler,
-                                        ACCESS_FINE_LOCATION);
-                                // call this after broadcasting so we do not increment
-                                // if we throw an exeption.
-                                incrementPendingBroadcasts();
-                            }
-                        } catch (PendingIntent.CanceledException e) {
-                            if (LOCAL_LOGV) {
-                                Slog.v(TAG, "Canceled proximity alert: " + alert, e);
-                            }
-                            if (intentsToRemove == null) {
-                                intentsToRemove = new ArrayList<PendingIntent>();
-                            }
-                            intentsToRemove.add(intent);
-                        }
-                    }
-                } else {
-                    // Mark alert for expiration
-                    if (LOCAL_LOGV) {
-                        Slog.v(TAG, "Expiring proximity alert: " + alert);
-                    }
-                    if (intentsToRemove == null) {
-                        intentsToRemove = new ArrayList<PendingIntent>();
-                    }
-                    intentsToRemove.add(alert.getIntent());
-                }
-            }
-
-            // Remove expired alerts
-            if (intentsToRemove != null) {
-                for (PendingIntent i : intentsToRemove) {
-                    ProximityAlert alert = mProximityAlerts.get(i);
-                    mProximitiesEntered.remove(alert);
-                    removeProximityAlertLocked(i);
-                }
-            }
-        }
-
-        // Note: this is called with the lock held.
-        public void onProviderDisabled(String provider) {
-            if (provider.equals(LocationManager.GPS_PROVIDER)) {
-                isGpsAvailable = false;
-            }
-        }
-
-        // Note: this is called with the lock held.
-        public void onProviderEnabled(String provider) {
-            // ignore
-        }
-
-        // Note: this is called with the lock held.
-        public void onStatusChanged(String provider, int status, Bundle extras) {
-            if ((provider.equals(LocationManager.GPS_PROVIDER)) &&
-                (status != LocationProvider.AVAILABLE)) {
-                isGpsAvailable = false;
-            }
-        }
-
-        public void onSendFinished(PendingIntent pendingIntent, Intent intent,
-                int resultCode, String resultData, Bundle resultExtras) {
-            // synchronize to ensure incrementPendingBroadcasts()
-            // is called before decrementPendingBroadcasts()
-            synchronized (this) {
-                decrementPendingBroadcasts();
-            }
-        }
-    }
-
+    @Override
     public void addProximityAlert(double latitude, double longitude,
-        float radius, long expiration, PendingIntent intent) {
+            float radius, long expiration, PendingIntent intent, String packageName) {
         validatePendingIntent(intent);
-        try {
-            synchronized (mLock) {
-                addProximityAlertLocked(latitude, longitude, radius, expiration, intent);
-            }
-        } catch (SecurityException se) {
-            throw se;
-        } catch (IllegalArgumentException iae) {
-            throw iae;
-        } catch (Exception e) {
-            Slog.e(TAG, "addProximityAlert got exception:", e);
-        }
-    }
-
-    private void addProximityAlertLocked(double latitude, double longitude,
-        float radius, long expiration, PendingIntent intent) {
-        if (LOCAL_LOGV) {
-            Slog.v(TAG, "addProximityAlert: latitude = " + latitude +
-                    ", longitude = " + longitude +
-                    ", expiration = " + expiration +
-                    ", intent = " + intent);
-        }
+        validatePackageName(Binder.getCallingUid(), packageName);
 
         // Require ability to access all providers for now
         if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) ||
@@ -1662,59 +1452,28 @@
             throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
         }
 
-        if (expiration != -1) {
-            expiration += System.currentTimeMillis();
-        }
-        ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(),
-                latitude, longitude, radius, expiration, intent);
-        mProximityAlerts.put(intent, alert);
+        if (LOCAL_LOGV) Slog.v(TAG, "addProximityAlert: lat=" + latitude + ", long=" + longitude +
+                ", radius=" + radius + ", exp=" + expiration + ", intent = " + intent);
 
-        if (mProximityReceiver == null) {
-            mProximityListener = new ProximityListener();
-            mProximityReceiver = new Receiver(mProximityListener);
-
-            for (int i = mProviders.size() - 1; i >= 0; i--) {
-                LocationProviderInterface provider = mProviders.get(i);
-                requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f,
-                        false, mProximityReceiver);
-            }
-        }
+        mGeofenceManager.addFence(latitude, longitude, radius, expiration, intent,
+                Binder.getCallingUid(), packageName);
     }
 
+    @Override
     public void removeProximityAlert(PendingIntent intent) {
-        try {
-            synchronized (mLock) {
-               removeProximityAlertLocked(intent);
-            }
-        } catch (SecurityException se) {
-            throw se;
-        } catch (IllegalArgumentException iae) {
-            throw iae;
-        } catch (Exception e) {
-            Slog.e(TAG, "removeProximityAlert got exception:", e);
-        }
+        if (intent == null) throw new NullPointerException("pending intent is null");
+
+        if (LOCAL_LOGV) Slog.v(TAG, "removeProximityAlert: intent = " + intent);
+
+        mGeofenceManager.removeFence(intent);
     }
 
-    private void removeProximityAlertLocked(PendingIntent intent) {
-        if (LOCAL_LOGV) {
-            Slog.v(TAG, "removeProximityAlert: intent = " + intent);
-        }
-
-        mProximityAlerts.remove(intent);
-        if (mProximityAlerts.size() == 0) {
-            if (mProximityReceiver != null) {
-                removeUpdatesLocked(mProximityReceiver);
-            }
-            mProximityReceiver = null;
-            mProximityListener = null;
-        }
-     }
-
     /**
      * @return null if the provider does not exist
      * @throws SecurityException if the provider is not allowed to be
      * accessed by the caller
      */
+    @Override
     public Bundle getProviderInfo(String provider) {
         try {
             synchronized (mLock) {
@@ -1752,6 +1511,7 @@
         return b;
     }
 
+    @Override
     public boolean isProviderEnabled(String provider) {
         try {
             synchronized (mLock) {
@@ -1765,6 +1525,7 @@
         }
     }
 
+    @Override
     public void reportLocation(Location location, boolean passive) {
         if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -1787,6 +1548,7 @@
         return isAllowedBySettingsLocked(provider);
     }
 
+    @Override
     public Location getLastKnownLocation(String provider) {
         if (LOCAL_LOGV) {
             Slog.v(TAG, "getLastKnownLocation: " + provider);
@@ -1869,7 +1631,7 @@
         int status = p.getStatus(extras);
 
         ArrayList<Receiver> deadReceivers = null;
-        
+
         // Broadcast location or status to all listeners
         final int N = records.size();
         for (int i=0; i<N; i++) {
@@ -1912,7 +1674,7 @@
                 }
             }
         }
-        
+
         if (deadReceivers != null) {
             for (int i=deadReceivers.size()-1; i>=0; i--) {
                 removeUpdatesLocked(deadReceivers.get(i));
@@ -2024,31 +1786,6 @@
                                     }
                                 }
                             }
-                            ArrayList<ProximityAlert> removedAlerts = null;
-                            for (ProximityAlert i : mProximityAlerts.values()) {
-                                if (i.mUid == uid) {
-                                    if (queryRestart) {
-                                        setResultCode(Activity.RESULT_OK);
-                                        return;
-                                    }
-                                    if (removedAlerts == null) {
-                                        removedAlerts = new ArrayList<ProximityAlert>();
-                                    }
-                                    if (!removedAlerts.contains(i)) {
-                                        removedAlerts.add(i);
-                                    }
-                                }
-                            }
-                            if (removedRecs != null) {
-                                for (int i=removedRecs.size()-1; i>=0; i--) {
-                                    removeUpdatesLocked(removedRecs.get(i));
-                                }
-                            }
-                            if (removedAlerts != null) {
-                                for (int i=removedAlerts.size()-1; i>=0; i--) {
-                                    removeProximityAlertLocked(removedAlerts.get(i).mIntent);
-                                }
-                            }
                         }
                     }
                 }
@@ -2089,6 +1826,10 @@
             // Called by main thread; divert work to LocationWorker.
             Message.obtain(mLocationHandler, MESSAGE_PACKAGE_UPDATED, packageName).sendToTarget();
         }
+        @Override
+        public void onPackageDisappeared(String packageName, int uid) {
+            mGeofenceManager.removeFence(packageName);
+        }
     };
 
     // Wake locks
@@ -2130,10 +1871,12 @@
 
     // Geocoder
 
+    @Override
     public boolean geocoderIsPresent() {
         return mGeocodeProvider != null;
     }
 
+    @Override
     public String getFromLocation(double latitude, double longitude, int maxResults,
             GeocoderParams params, List<Address> addrs) {
         if (mGeocodeProvider != null) {
@@ -2144,6 +1887,7 @@
     }
 
 
+    @Override
     public String getFromLocationName(String locationName,
             double lowerLeftLatitude, double lowerLeftLongitude,
             double upperRightLatitude, double upperRightLongitude, int maxResults,
@@ -2169,9 +1913,10 @@
         if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
             PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
-        }            
+        }
     }
 
+    @Override
     public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
         boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
         boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
@@ -2207,6 +1952,7 @@
         Binder.restoreCallingIdentity(identity);
     }
 
+    @Override
     public void removeTestProvider(String provider) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2231,6 +1977,7 @@
         }
     }
 
+    @Override
     public void setTestProviderLocation(String provider, Location loc) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2245,6 +1992,7 @@
         }
     }
 
+    @Override
     public void clearTestProviderLocation(String provider) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2256,6 +2004,7 @@
         }
     }
 
+    @Override
     public void setTestProviderEnabled(String provider, boolean enabled) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2278,6 +2027,7 @@
         }
     }
 
+    @Override
     public void clearTestProviderEnabled(String provider) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2293,6 +2043,7 @@
         }
     }
 
+    @Override
     public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2304,6 +2055,7 @@
         }
     }
 
+    @Override
     public void clearTestProviderStatus(String provider) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
@@ -2320,7 +2072,8 @@
             Slog.d(TAG, log);
         }
     }
-    
+
+    @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -2329,7 +2082,7 @@
                     + ", uid=" + Binder.getCallingUid());
             return;
         }
-        
+
         synchronized (mLock) {
             pw.println("Current Location Manager state:");
             pw.println("  sProvidersLoaded=" + sProvidersLoaded);
@@ -2361,36 +2114,20 @@
                 pw.println("    " + i.getKey() + ":");
                 i.getValue().dump(new PrintWriterPrinter(pw), "      ");
             }
-            if (mProximityAlerts.size() > 0) {
-                pw.println("  Proximity Alerts:");
-                for (Map.Entry<PendingIntent, ProximityAlert> i
-                        : mProximityAlerts.entrySet()) {
-                    pw.println("    " + i.getKey() + ":");
-                    i.getValue().dump(pw, "      ");
-                }
-            }
-            if (mProximitiesEntered.size() > 0) {
-                pw.println("  Proximities Entered:");
-                for (ProximityAlert i : mProximitiesEntered) {
-                    pw.println("    " + i + ":");
-                    i.dump(pw, "      ");
-                }
-            }
-            pw.println("  mProximityReceiver=" + mProximityReceiver);
-            pw.println("  mProximityListener=" + mProximityListener);
+            mGeofenceManager.dump(pw);
             if (mEnabledProviders.size() > 0) {
                 pw.println("  Enabled Providers:");
                 for (String i : mEnabledProviders) {
                     pw.println("    " + i);
                 }
-                
+
             }
             if (mDisabledProviders.size() > 0) {
                 pw.println("  Disabled Providers:");
                 for (String i : mDisabledProviders) {
                     pw.println("    " + i);
                 }
-                
+
             }
             if (mMockProviders.size() > 0) {
                 pw.println("  Mock Providers:");
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 09792f5..c3f3a5d 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -78,6 +78,7 @@
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
 import java.util.concurrent.CountDownLatch;
+import android.bluetooth.BluetoothTetheringDataTracker;
 
 /**
  * @hide
@@ -121,6 +122,7 @@
 
         public static final int InterfaceChange           = 600;
         public static final int BandwidthControl          = 601;
+        public static final int InterfaceClassActivity    = 613;
     }
 
     /**
@@ -278,6 +280,20 @@
     }
 
     /**
+     * Notify our observers of a change in the data activity state of the interface
+     */
+    private void notifyInterfaceClassActivity(String label, boolean active) {
+        final int length = mObservers.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
+            } catch (RemoteException e) {
+            }
+        }
+        mObservers.finishBroadcast();
+    }
+
+    /**
      * Prepare native daemon once connected, enabling modules and pushing any
      * existing in-memory rules.
      */
@@ -403,6 +419,19 @@
                     throw new IllegalStateException(
                             String.format("Invalid event from daemon (%s)", raw));
                     // break;
+            case NetdResponseCode.InterfaceClassActivity:
+                    /*
+                     * An network interface class state changed (active/idle)
+                     * Format: "NNN IfaceClass <active/idle> <label>"
+                     */
+                    if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
+                        throw new IllegalStateException(
+                                String.format("Invalid event from daemon (%s)", raw));
+                    }
+                    boolean isActive = cooked[2].equals("active");
+                    notifyInterfaceClassActivity(cooked[3], isActive);
+                    return true;
+                    // break;
             default: break;
             }
             return false;
@@ -780,6 +809,36 @@
         return event.getMessage().endsWith("started");
     }
 
+    // TODO(BT) Remove
+    public void startReverseTethering(String iface)
+             throws IllegalStateException {
+        if (DBG) Slog.d(TAG, "startReverseTethering in");
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        // cmd is "tether start first_start first_stop second_start second_stop ..."
+        // an odd number of addrs will fail
+        String cmd = "tether start-reverse";
+        cmd += " " + iface;
+        if (DBG) Slog.d(TAG, "startReverseTethering cmd: " + cmd);
+        try {
+            mConnector.doCommand(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Unable to communicate to native daemon");
+        }
+        BluetoothTetheringDataTracker.getInstance().startReverseTether(iface);
+
+    }
+
+    // TODO(BT) Remove
+    public void stopReverseTethering() throws IllegalStateException {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.doCommand("tether stop-reverse");
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException("Unable to communicate to native daemon to stop tether");
+        }
+        BluetoothTetheringDataTracker.getInstance().stopReverseTether();
+    }
+
     @Override
     public void tetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ec8a4ab..2185456 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -36,8 +36,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.provider.Settings;
-import android.server.BluetoothA2dpService;
-import android.server.BluetoothService;
 import android.server.search.SearchManagerService;
 import android.service.dreams.DreamManagerService;
 import android.util.DisplayMetrics;
@@ -130,8 +128,7 @@
         IPackageManager pm = null;
         Context context = null;
         WindowManagerService wm = null;
-        BluetoothService bluetooth = null;
-        BluetoothA2dpService bluetoothA2dp = null;
+        BluetoothManagerService bluetooth = null;
         DockObserver dock = null;
         UsbService usb = null;
         SerialService serial = null;
@@ -245,23 +242,9 @@
             } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                 Slog.i(TAG, "No Bluetooth Service (factory test)");
             } else {
-                Slog.i(TAG, "Bluetooth Service");
-                bluetooth = new BluetoothService(context);
-                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
-                bluetooth.initAfterRegistration();
-
-                if (!"0".equals(SystemProperties.get("system_init.startaudioservice"))) {
-                    bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
-                    ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
-                                              bluetoothA2dp);
-                    bluetooth.initAfterA2dpRegistration();
-                }
-
-                int bluetoothOn = Settings.Secure.getInt(mContentResolver,
-                    Settings.Secure.BLUETOOTH_ON, 0);
-                if (bluetoothOn != 0) {
-                    bluetooth.enable();
-                }
+                Slog.i(TAG, "Bluetooth Manager Service");
+                bluetooth = new BluetoothManagerService(context);
+                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
             }
 
         } catch (RuntimeException e) {
@@ -748,7 +731,6 @@
         final StatusBarManagerService statusBarF = statusBar;
         final DreamManagerService dreamyF = dreamy;
         final InputManagerService inputManagerF = inputManager;
-        final BluetoothService bluetoothF = bluetooth;
 
         // We now tell the activity manager it is okay to run third party
         // code.  It will call back into us once it has gotten to the state
@@ -861,7 +843,8 @@
                     reportWtf("making DreamManagerService ready", e);
                 }
                 try {
-                    if (inputManagerF != null) inputManagerF.systemReady(bluetoothF);
+                    // TODO(BT) Pass parameter to input manager
+                    if (inputManagerF != null) inputManagerF.systemReady();
                 } catch (Throwable e) {
                     reportWtf("making InputManagerService ready", e);
                 }
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index f35a5af..98e6dc0 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -195,6 +195,7 @@
 
         public void interfaceRemoved(String iface) {}
         public void limitReached(String limitName, String iface) {}
+        public void interfaceClassDataActivityChanged(String label, boolean active) {}
     }
 
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 60085f4..be05cc7 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -12931,7 +12931,8 @@
          * processes) from sending protected broadcasts.
          */
         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
-                || callingUid == Process.SHELL_UID || callingUid == 0) {
+            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
+            callingUid == 0) {
             // Always okay.
         } else if (callerApp == null || !callerApp.persistent) {
             try {
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 5aa3a29..e4f1f7a 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -319,6 +319,8 @@
 
     public void limitReached(String limitName, String iface) {}
 
+    public void interfaceClassDataActivityChanged(String label, boolean active) {}
+
     public int tether(String iface) {
         if (DBG) Log.d(TAG, "Tethering " + iface);
         TetherInterfaceSM sm = null;
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 4b82037..b12d597 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -291,6 +291,9 @@
     public void limitReached(String limit, String interfaze) {
     }
 
+    public void interfaceClassDataActivityChanged(String label, boolean active) {
+    }
+
     private void enforceControlPermission() {
         // System user is allowed to control VPN.
         if (Binder.getCallingUid() == Process.SYSTEM_UID) {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index e7afb1a..21100e2 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -57,7 +57,6 @@
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
-import android.server.BluetoothService;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -110,7 +109,6 @@
     private final Callbacks mCallbacks;
     private final InputManagerHandler mHandler;
     private boolean mSystemReady;
-    private BluetoothService mBluetoothService;
     private NotificationManager mNotificationManager;
 
     // Persistent data store.  Must be locked each time during use.
@@ -238,11 +236,11 @@
         updateShowTouchesFromSettings();
     }
 
-    public void systemReady(BluetoothService bluetoothService) {
+    // TODO(BT) Pass in paramter for bluetooth system
+    public void systemReady() {
         if (DEBUG) {
             Slog.d(TAG, "System ready.");
         }
-        mBluetoothService = bluetoothService;
         mNotificationManager = (NotificationManager)mContext.getSystemService(
                 Context.NOTIFICATION_SERVICE);
         mSystemReady = true;
@@ -1398,9 +1396,9 @@
 
     // Native callback.
     private String getDeviceAlias(String uniqueId) {
-        if (mBluetoothService != null &&
-                BluetoothAdapter.checkBluetoothAddress(uniqueId)) {
-            return mBluetoothService.getRemoteAlias(uniqueId);
+        if (BluetoothAdapter.checkBluetoothAddress(uniqueId)) {
+            // TODO(BT) mBluetoothService.getRemoteAlias(uniqueId)
+            return null;
         }
         return null;
     }
diff --git a/services/java/com/android/server/location/Geofence.java b/services/java/com/android/server/location/Geofence.java
new file mode 100644
index 0000000..f63607a
--- /dev/null
+++ b/services/java/com/android/server/location/Geofence.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.location;
+
+import android.location.Location;
+
+/**
+ * Represents a simple circular GeoFence.
+ */
+public class Geofence {
+    public final static int FLAG_ENTER = 0x01;
+    public final static int FLAG_EXIT = 0x02;
+
+    static final int STATE_UNKNOWN = 0;
+    static final int STATE_INSIDE = 1;
+    static final int STATE_OUTSIDE = 2;
+
+    final double mLatitude;
+    final double mLongitude;
+    final float mRadius;
+    final Location mLocation;
+
+    int mState;  // current state
+    double mDistance;  // current distance to center of fence
+
+    public Geofence(double latitude, double longitude, float radius, Location prevLocation) {
+        mState = STATE_UNKNOWN;
+
+        mLatitude = latitude;
+        mLongitude = longitude;
+        mRadius = radius;
+
+        mLocation = new Location("");
+        mLocation.setLatitude(latitude);
+        mLocation.setLongitude(longitude);
+
+        if (prevLocation != null) {
+            processLocation(prevLocation);
+        }
+    }
+
+    /**
+     * Process a new location.
+     * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise
+     */
+    public int processLocation(Location location) {
+        mDistance = mLocation.distanceTo(location);
+
+        int prevState = mState;
+        //TODO: inside/outside detection could be made more rigorous
+        boolean inside = mDistance <= Math.max(mRadius, location.getAccuracy());
+        if (inside) {
+            mState = STATE_INSIDE;
+        } else {
+            mState = STATE_OUTSIDE;
+        }
+
+        if (prevState != 0 && mState != prevState) {
+            if (mState == STATE_INSIDE) return FLAG_ENTER;
+            if (mState == STATE_OUTSIDE) return FLAG_EXIT;
+        }
+        return 0;
+    }
+
+    public double getDistance() {
+        return mDistance;
+    }
+
+    @Override
+    public String toString() {
+        String state;
+        switch (mState) {
+            case STATE_INSIDE:
+                state = "IN";
+                break;
+            case STATE_OUTSIDE:
+                state = "OUT";
+                break;
+            default:
+                state = "?";
+        }
+        return String.format("(%.4f, %.4f r=%.0f d=%.0f %s)", mLatitude, mLongitude, mRadius,
+                mDistance, state);
+    }
+}
diff --git a/services/java/com/android/server/location/GeofenceManager.java b/services/java/com/android/server/location/GeofenceManager.java
new file mode 100644
index 0000000..b3f53ea
--- /dev/null
+++ b/services/java/com/android/server/location/GeofenceManager.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 20012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import android.Manifest.permission;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.SystemClock;
+
+public class GeofenceManager implements LocationListener, PendingIntent.OnFinished {
+    static final String TAG = "GeofenceManager";
+
+    /**
+     * Assume a maximum land speed, as a heuristic to throttle location updates.
+     * (Air travel should result in an airplane mode toggle which will
+     * force a new location update anyway).
+     */
+    static final int MAX_SPEED_M_S = 100;  // 360 km/hr (high speed train)
+
+    class GeofenceWrapper {
+        final Geofence fence;
+        final long expiry;
+        final String packageName;
+        final PendingIntent intent;
+
+        public GeofenceWrapper(Geofence fence, long expiry, String packageName,
+                PendingIntent intent) {
+            this.fence = fence;
+            this.expiry = expiry;
+            this.packageName = packageName;
+            this.intent = intent;
+        }
+    }
+
+    final Context mContext;
+    final LocationManager mLocationManager;
+    final PowerManager.WakeLock mWakeLock;
+    final Looper mLooper;  // looper thread to take location updates on
+
+    // access to members below is synchronized on this
+    Location mLastLocation;
+    List<GeofenceWrapper> mFences = new LinkedList<GeofenceWrapper>();
+
+    public GeofenceManager(Context context) {
+        mContext = context;
+        mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mLooper = Looper.myLooper();
+        mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this);
+    }
+
+    public void addFence(double latitude, double longitude, float radius, long expiration,
+            PendingIntent intent, int uid, String packageName) {
+        long expiry = SystemClock.elapsedRealtime() + expiration;
+        if (expiration < 0) {
+            expiry = Long.MAX_VALUE;
+        }
+        Geofence fence = new Geofence(latitude, longitude, radius, mLastLocation);
+        GeofenceWrapper fenceWrapper = new GeofenceWrapper(fence, expiry, packageName, intent);
+
+        synchronized (this) {
+            mFences.add(fenceWrapper);
+            updateProviderRequirements();
+        }
+    }
+
+    public void removeFence(PendingIntent intent) {
+        synchronized (this) {
+            Iterator<GeofenceWrapper> iter = mFences.iterator();
+            while (iter.hasNext()) {
+                GeofenceWrapper fenceWrapper = iter.next();
+                if (fenceWrapper.intent.equals(intent)) {
+                    iter.remove();
+                }
+            }
+            updateProviderRequirements();
+        }
+    }
+
+    public void removeFence(String packageName) {
+        synchronized (this) {
+            Iterator<GeofenceWrapper> iter = mFences.iterator();
+            while (iter.hasNext()) {
+                GeofenceWrapper fenceWrapper = iter.next();
+                if (fenceWrapper.packageName.equals(packageName)) {
+                    iter.remove();
+                }
+            }
+            updateProviderRequirements();
+        }
+    }
+
+    void removeExpiredFences() {
+        synchronized (this) {
+            long time = SystemClock.elapsedRealtime();
+            Iterator<GeofenceWrapper> iter = mFences.iterator();
+            while (iter.hasNext()) {
+                GeofenceWrapper fenceWrapper = iter.next();
+                if (fenceWrapper.expiry < time) {
+                    iter.remove();
+                }
+            }
+        }
+    }
+
+    void processLocation(Location location) {
+        List<PendingIntent> enterIntents = new LinkedList<PendingIntent>();
+        List<PendingIntent> exitIntents = new LinkedList<PendingIntent>();
+
+        synchronized (this) {
+            mLastLocation = location;
+
+            removeExpiredFences();
+
+            for (GeofenceWrapper fenceWrapper : mFences) {
+                int event = fenceWrapper.fence.processLocation(location);
+                if ((event & Geofence.FLAG_ENTER) != 0) {
+                    enterIntents.add(fenceWrapper.intent);
+                }
+                if ((event & Geofence.FLAG_EXIT) != 0) {
+                    exitIntents.add(fenceWrapper.intent);
+                }
+            }
+            updateProviderRequirements();
+        }
+
+        // release lock before sending intents
+        for (PendingIntent intent : exitIntents) {
+            sendIntentExit(intent);
+        }
+        for (PendingIntent intent : enterIntents) {
+            sendIntentEnter(intent);
+        }
+    }
+
+    void sendIntentEnter(PendingIntent pendingIntent) {
+        Intent intent = new Intent();
+        intent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true);
+        sendIntent(pendingIntent, intent);
+    }
+
+    void sendIntentExit(PendingIntent pendingIntent) {
+        Intent intent = new Intent();
+        intent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);
+        sendIntent(pendingIntent, intent);
+    }
+
+    void sendIntent(PendingIntent pendingIntent, Intent intent) {
+        try {
+            mWakeLock.acquire();
+            pendingIntent.send(mContext, 0, intent, this, null, permission.ACCESS_FINE_LOCATION);
+        } catch (PendingIntent.CanceledException e) {
+            removeFence(pendingIntent);
+            mWakeLock.release();
+        }
+    }
+
+    void updateProviderRequirements() {
+        synchronized (this) {
+            double minDistance = Double.MAX_VALUE;
+            for (GeofenceWrapper alert : mFences) {
+                if (alert.fence.getDistance() < minDistance) {
+                    minDistance = alert.fence.getDistance();
+                }
+            }
+
+            if (minDistance == Double.MAX_VALUE) {
+                disableLocation();
+            } else {
+                int intervalMs = (int)(minDistance * 1000) / MAX_SPEED_M_S;
+                setLocationInterval(intervalMs);
+            }
+        }
+    }
+
+    void setLocationInterval(int intervalMs) {
+        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, intervalMs, 0, this,
+                mLooper);
+    }
+
+    void disableLocation() {
+        mLocationManager.removeUpdates(this);
+    }
+
+    @Override
+    public void onLocationChanged(Location location) {
+        processLocation(location);
+    }
+
+    @Override
+    public void onStatusChanged(String provider, int status, Bundle extras) { }
+
+    @Override
+    public void onProviderEnabled(String provider) { }
+
+    @Override
+    public void onProviderDisabled(String provider) { }
+
+    @Override
+    public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
+            String resultData, Bundle resultExtras) {
+        mWakeLock.release();
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("  Geofences:");
+        for (GeofenceWrapper fenceWrapper : mFences) {
+            pw.append("    ");
+            pw.append(fenceWrapper.packageName);
+            pw.append(" ");
+            pw.append(fenceWrapper.fence.toString());
+            pw.append("\n");
+        }
+    }
+}
diff --git a/services/java/com/android/server/net/NetworkAlertObserver.java b/services/java/com/android/server/net/NetworkAlertObserver.java
index 0d1c3b2..9e181c5 100644
--- a/services/java/com/android/server/net/NetworkAlertObserver.java
+++ b/services/java/com/android/server/net/NetworkAlertObserver.java
@@ -41,4 +41,7 @@
     public void interfaceAdded(String iface) {
         // ignored; interface changes come through ConnectivityService
     }
+    public void interfaceClassDataActivityChanged(String label, boolean active) {
+        // ignored; interface changes come through ConnectivityService
+    }
 }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index e1ab58b..ffb3fa6 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -173,6 +173,7 @@
     private static final int RADIO_UID = Process.PHONE_UID;
     private static final int LOG_UID = Process.LOG_UID;
     private static final int NFC_UID = Process.NFC_UID;
+    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
 
     private static final boolean GET_CERTIFICATES = true;
 
@@ -903,6 +904,7 @@
         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
         mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
+        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
 
         String separateProcesses = SystemProperties.get("debug.separate_processes");
         if (separateProcesses != null && separateProcesses.length() > 0) {
diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
index 5f2f428..a3770d7 100644
--- a/services/java/com/android/server/power/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -23,7 +23,7 @@
 import android.app.IActivityManager;
 import android.app.ProgressDialog;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothManager;
 import android.nfc.NfcAdapter;
 import android.nfc.INfcAdapter;
 import android.content.BroadcastReceiver;
@@ -384,9 +384,9 @@
                         INfcAdapter.Stub.asInterface(ServiceManager.checkService("nfc"));
                 final ITelephony phone =
                         ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-                final IBluetooth bluetooth =
-                        IBluetooth.Stub.asInterface(ServiceManager.checkService(
-                                BluetoothAdapter.BLUETOOTH_SERVICE));
+                final IBluetoothManager bluetooth =
+                        IBluetoothManager.Stub.asInterface(ServiceManager.checkService(
+                                BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE));
 
                 try {
                     nfcOff = nfc == null ||
@@ -401,8 +401,7 @@
                 }
 
                 try {
-                    bluetoothOff = bluetooth == null ||
-                                   bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+                    bluetoothOff = bluetooth == null || !bluetooth.isEnabled();
                     if (!bluetoothOff) {
                         Log.w(TAG, "Disabling Bluetooth...");
                         bluetooth.disable(false);  // disable but don't persist new state
@@ -428,8 +427,7 @@
                 while (SystemClock.elapsedRealtime() < endTime) {
                     if (!bluetoothOff) {
                         try {
-                            bluetoothOff =
-                                    bluetooth.getBluetoothState() == BluetoothAdapter.STATE_OFF;
+                            bluetoothOff = !bluetooth.isEnabled();
                         } catch (RemoteException ex) {
                             Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
                             bluetoothOff = true;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 2c7d36f..4227def 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9458,12 +9458,6 @@
             mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
                     mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight,
                     mDisplay.getRotation());
-
-            if (!mAnimator.mScreenRotationAnimation.hasScreenshot()) {
-                Surface.freezeDisplay(0);
-            }
-        } else {
-            Surface.freezeDisplay(0);
         }
     }
 
@@ -9506,7 +9500,6 @@
             }
             updateRotation = true;
         }
-        Surface.unfreezeDisplay(0);
 
         mInputMonitor.thawInputDispatchingLw();
 
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index dd34b2e..f08204f 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -697,10 +697,6 @@
                     mSurface.setAlpha(0);
                     mSurfaceShown = false;
                     mSurface.hide();
-                    if ((mWin.mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
-                        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "DITHER", null);
-                        mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER);
-                    }
                 } catch (RuntimeException e) {
                     Slog.w(TAG, "Error creating surface in " + w, e);
                     mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);