Merge changes from topics "rtt_access_point_api_name", "rtt_aware"

* changes:
  [RTT2] Rename API Ap -> AccessPoint, timestamp clarification
  [RTT2] Facade for RTT to Aware peers
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java
index 0828e74..e965d5a 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java
@@ -25,8 +25,13 @@
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
 import android.os.ParcelUuid;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 
 import com.googlecode.android_scripting.Log;
+import com.googlecode.android_scripting.facade.EventFacade;
 import com.googlecode.android_scripting.facade.FacadeManager;
 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
 import com.googlecode.android_scripting.rpc.Rpc;
@@ -42,12 +47,24 @@
   private static boolean sIsHidReady = false;
   private static BluetoothInputDevice sHidProfile = null;
 
+  private final EventFacade mEventFacade;
+
   public BluetoothHidFacade(FacadeManager manager) {
     super(manager);
     mService = manager.getService();
     mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
     mBluetoothAdapter.getProfileProxy(mService, new HidServiceListener(),
         BluetoothProfile.INPUT_DEVICE);
+    IntentFilter pkgFilter = new IntentFilter();
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_PROTOCOL_MODE_CHANGED);
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_HANDSHAKE);
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_REPORT);
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_VIRTUAL_UNPLUG_STATUS);
+    pkgFilter.addAction(BluetoothInputDevice.ACTION_IDLE_TIME_CHANGED);
+    mService.registerReceiver(mHidServiceBroadcastReceiver, pkgFilter);
+    Log.d(HidServiceBroadcastReceiver.TAG + " registered");
+    mEventFacade = manager.getReceiver(EventFacade.class);
   }
 
   class HidServiceListener implements BluetoothProfile.ServiceListener {
@@ -63,6 +80,56 @@
     }
   }
 
+  class HidServiceBroadcastReceiver extends BroadcastReceiver {
+      private static final String TAG = "HidServiceBroadcastReceiver";
+
+      @Override
+      public void onReceive(Context context, Intent intent) {
+          String action = intent.getAction();
+          Log.d(TAG + " action=" + action);
+
+          switch (action) {
+              case BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED: {
+                  int previousState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
+                  int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+                  Log.d("Connection state changed: " + previousState + " -> " + state);
+              }
+              break;
+              case BluetoothInputDevice.ACTION_PROTOCOL_MODE_CHANGED: {
+                  int status = intent.getIntExtra(BluetoothInputDevice.EXTRA_STATUS, -1);
+                  Log.d("Protocol mode changed: " + status);
+              }
+              break;
+              case BluetoothInputDevice.ACTION_HANDSHAKE: {
+                  int status = intent.getIntExtra(BluetoothInputDevice.EXTRA_STATUS, -1);
+                  Log.d("Handshake received: " + status);
+              }
+              break;
+              case BluetoothInputDevice.ACTION_REPORT: {
+                  char[] report = intent.getCharArrayExtra(BluetoothInputDevice.EXTRA_REPORT);
+                  Log.d("Received report: " + String.valueOf(report));
+              }
+              break;
+              case BluetoothInputDevice.ACTION_VIRTUAL_UNPLUG_STATUS: {
+                  int status = intent.getIntExtra(
+                          BluetoothInputDevice.EXTRA_VIRTUAL_UNPLUG_STATUS, -1);
+                  Log.d("Virtual unplug status: " + status);
+              }
+              break;
+              case BluetoothInputDevice.ACTION_IDLE_TIME_CHANGED: {
+                  int idleTime = intent.getIntExtra(BluetoothInputDevice.EXTRA_IDLE_TIME, -1);
+                  Log.d("Idle time changed: " + idleTime);
+              }
+              break;
+              default:
+                  break;
+          }
+      }
+  }
+
+  private final BroadcastReceiver mHidServiceBroadcastReceiver = new HidServiceBroadcastReceiver();
+
+
   public Boolean hidConnect(BluetoothDevice device) {
     if (sHidProfile == null) return false;
     return sHidProfile.connect(device);
@@ -134,15 +201,24 @@
           String deviceID,
           @RpcParameter(name = "type")
           @RpcDefault(value = "1")
-          String type,
+          Integer type,
           @RpcParameter(name = "report")
           String report) throws Exception {
       BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
               deviceID);
-      Log.d("type " + type.getBytes()[0]);
-      return sHidProfile.setReport(device, type.getBytes()[0], report);
+      Log.d("type=" + type);
+      return sHidProfile.setReport(device, (byte) (int) type, report);
   }
 
+    /**
+     * Sends the Get_Report command to the given connected HID input device.
+     * @param deviceID name or MAC address or the HID input device
+     * @param type Bluetooth HID report type
+     * @param reportId ID for the requesting report
+     * @param buffSize advised buffer size on the Bluetooth HID host
+     * @return True if successfully sent the command; otherwise false
+     * @throws Exception error from Bluetooth HidService
+     */
   @Rpc(description = "Send Get_Report command to the connected HID input device.")
   public Boolean bluetoothHidGetReport(
           @RpcParameter(name = "deviceID",
@@ -150,17 +226,23 @@
           String deviceID,
           @RpcParameter(name = "type")
           @RpcDefault(value = "1")
-          String type,
+          Integer type,
           @RpcParameter(name = "reportId")
-          String reportId,
+          Integer reportId,
           @RpcParameter(name = "buffSize")
           Integer buffSize) throws Exception {
       BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
               deviceID);
-      Log.d("type " + type.getBytes()[0] + "reportId " + reportId.getBytes()[0]);
-      return sHidProfile.getReport(device, type.getBytes()[0], reportId.getBytes()[0], buffSize);
+      Log.d("type=" + type + " reportId=" + reportId);
+      return sHidProfile.getReport(device, (byte) (int) type, (byte) (int) reportId, buffSize);
   }
-
+  /**
+   * Sends a data report to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @param report the report payload
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
   @Rpc(description = "Send data to a connected HID device.")
   public Boolean bluetoothHidSendData(
           @RpcParameter(name = "deviceID",
@@ -173,6 +255,13 @@
       return sHidProfile.sendData(device, report);
   }
 
+
+  /**
+   * Sends the virtual cable unplug command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
   @Rpc(description = "Send virtual unplug to a connected HID device.")
   public Boolean bluetoothHidVirtualUnplug(
           @RpcParameter(name = "deviceID",
@@ -183,6 +272,112 @@
       return sHidProfile.virtualUnplug(device);
   }
 
+  /**
+   * Sends the Set_Priority command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @param priority priority level
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Set priority of the profile")
+
+  public Boolean bluetoothHidSetPriority(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID,
+          @RpcParameter(name = "priority")
+                  Integer priority) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.setPriority(device, priority);
+  }
+
+  /**
+   * Sends the Get_Priority command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @return The value of the HID input device priority
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Get priority of the profile")
+  public Integer bluetoothHidGetPriority(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.getPriority(device);
+  }
+
+  /**
+   * Sends the Set_Protocol_Mode command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @param protocolMode protocol mode
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Send Set_Protocol_Mode command to the connected HID input device.")
+  public Boolean bluetoothHidSetProtocolMode(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID,
+          @RpcParameter(name = "protocolMode")
+                  Integer protocolMode) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.setProtocolMode(device, protocolMode);
+  }
+
+  /**
+   * Sends the Get_Protocol_Mode command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Send Get_Protocol_Mode command to the connected HID input device.")
+  public Boolean bluetoothHidGetProtocolMode(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.getProtocolMode(device);
+  }
+
+  /**
+   * Sends the Set_Idle_Time command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @param idleTime idle time
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Send Set_Idle_Time command to the connected HID input device.")
+  public Boolean bluetoothHidSetIdleTime(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID,
+          @RpcParameter(name = "idleTime")
+                  Integer idleTime) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.setIdleTime(device, (byte) (int) idleTime);
+  }
+
+  /**
+   * Sends the Get_Idle_Time command to the given connected HID input device.
+   * @param deviceID name or MAC address or the HID input device
+   * @return True if successfully sent the command; otherwise false
+   * @throws Exception error from Bluetooth HidService
+   */
+  @Rpc(description = "Send Get_Idle_Time command to the connected HID input device.")
+  public Boolean bluetoothHidGetIdleTime(
+          @RpcParameter(name = "deviceID",
+                  description = "Name or MAC address of a bluetooth device.")
+                  String deviceID) throws Exception {
+      BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(),
+              deviceID);
+      return sHidProfile.getIdleTime(device);
+  }
+
   @Rpc(description = "Test byte transfer.")
   public byte[] testByte() {
       byte[] bts = {0b01,0b10,0b11,0b100};
@@ -193,3 +388,4 @@
   public void shutdown() {
   }
 }
+
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 84be1ab..d2eb022 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -45,6 +45,7 @@
 import com.googlecode.android_scripting.facade.telephony.TelephonyConstants;
 import com.googlecode.android_scripting.facade.telephony.TelephonyUtils;
 
+import android.annotation.NonNull;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
@@ -102,6 +103,8 @@
 import android.util.DisplayMetrics;
 import android.util.SparseArray;
 
+import static com.googlecode.android_scripting.ConvertUtils.toNonNullString;
+
 public class JsonBuilder {
 
     @SuppressWarnings("unchecked")
@@ -828,15 +831,20 @@
         return url;
     }
 
-    private static JSONObject buildPhoneAccount(PhoneAccount data)
+    /**
+     * Builds a json representation of a {@link PhoneAccount}.
+     * @param data The PhoneAccount convert to JSON.
+     * @return A JSONObject representation of a {@link PhoneAccount}.
+     * @throws JSONException
+     */
+    private static JSONObject buildPhoneAccount(@NonNull PhoneAccount data)
             throws JSONException {
         JSONObject acct = new JSONObject();
-        acct.put("Address", data.getAddress().toSafeString());
-        acct.put("SubscriptionAddress", data.getSubscriptionAddress()
-                .toSafeString());
-        acct.put("Label", ((data.getLabel() != null) ? data.getLabel().toString() : ""));
-        acct.put("ShortDescription", ((data.getShortDescription() != null) ? data
-                .getShortDescription().toString() : ""));
+        acct.put("Address", toNonNullString(data.getAddress(), Uri::toSafeString));
+        acct.put("SubscriptionAddress", toNonNullString(data.getSubscriptionAddress(),
+                Uri::toSafeString));
+        acct.put("Label", toNonNullString(data.getLabel()));
+        acct.put("ShortDescription", toNonNullString(data.getShortDescription()));
         return acct;
     }
 
diff --git a/ScriptingLayerForAndroid/jni/Android.mk b/ScriptingLayerForAndroid/jni/Android.mk
index d9bf0e4..c4ed0a2 100644
--- a/ScriptingLayerForAndroid/jni/Android.mk
+++ b/ScriptingLayerForAndroid/jni/Android.mk
@@ -20,7 +20,9 @@
 
 LOCAL_SRC_FILES := com_googlecode_android_scripting_Exec.cpp
 
-LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += \
+    -Wall -Werror \
+    -Wno-unused-parameter \
 
 LOCAL_SHARED_LIBRARIES := \
     liblog
diff --git a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java b/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
index fc7288a..b18d830 100644
--- a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
+++ b/Utils/src/com/googlecode/android_scripting/ConvertUtils.java
@@ -16,6 +16,10 @@
 
 package com.googlecode.android_scripting;
 
+import android.annotation.NonNull;
+
+import com.google.common.base.Strings;
+
 public class ConvertUtils {
     /**
      * Converts a String of comma separated bytes to a byte array
@@ -61,4 +65,42 @@
         return ret;
     }
 
+    /**
+     * An interface for
+     * @param <T1> The type of the caller.
+     * @param <T2> The returned type of the call.
+     */
+    public interface IFunction<T1, T2> {
+        T2 call(T1 t1);
+    }
+
+    /**
+     * Calls a given function on an object, and returns a NonNull String of the return value.
+     * @param obj The object to get the string data from.
+     * @param function The function or method to call.
+     * @param <T1> The type of the object.
+     * @param <T2> The type of the function return type.
+     * @return A string guaranteed not to be null.
+     */
+    public static <T1, T2> String toNonNullString(T1 obj, @NonNull IFunction<T1, T2> function) {
+        if (obj == null) {
+            return "";
+        } else {
+            return toNonNullString(function.call(obj));
+        }
+    }
+
+    /**
+     * Returns toString() or an empty string if {@code obj} or result is null.
+     * @param obj The object to call toString() on.
+     * @param <T> The type of the object.
+     * @return A string guaranteed not to be null.
+     */
+    public static <T> String toNonNullString(T obj) {
+        if (obj == null) {
+            return "";
+        } else {
+            return Strings.nullToEmpty(obj.toString());
+        }
+    }
 }