Merge branch 'ble' into discovery

Change-Id: Ifd34c03eba21fd4738940f64e7624a5edbddd9ed
diff --git a/android-lib/src/main/java/io/v/android/libs/discovery/ble/NativeScanHandler.java b/android-lib/src/main/java/io/v/android/libs/discovery/ble/NativeScanHandler.java
new file mode 100644
index 0000000..574a443
--- /dev/null
+++ b/android-lib/src/main/java/io/v/android/libs/discovery/ble/NativeScanHandler.java
@@ -0,0 +1,31 @@
+package io.v.android.libs.discovery.ble;
+
+import io.v.impl.google.lib.discovery.ScanHandler;
+import io.v.x.ref.lib.discovery.Advertisement;
+
+/**
+ * An implementation of the ScanHandler for use by the discovery frameework.
+ */
+class NativeScanHandler implements ScanHandler{
+    /**
+     * A pointer to the the native channel.
+     */
+    private long nativeChan;
+
+    NativeScanHandler(long nativeChan) {
+        this.nativeChan = nativeChan;
+    }
+
+    private native void nativeHandleUpdate(Advertisement adv, long chan);
+    private native void nativeCleanup(long chan);
+
+    @Override
+    public void handleUpdate(Advertisement advertisement) {
+        nativeHandleUpdate(advertisement, nativeChan);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        nativeCleanup(nativeChan);
+    }
+}
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java b/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
index 4bf4ab2..0cef869 100644
--- a/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/DeviceCache.java
@@ -27,6 +27,7 @@
  * so we only refetch the data if it hash changed.
  */
 public class DeviceCache {
+
     final private Map<Long, CacheEntry> cachedDevices = new HashMap<>();
     final private Map<String, CacheEntry> knownIds = new HashMap<>();
 
diff --git a/lib/src/main/java/io/v/impl/google/lib/discovery/VDiscoveryImpl.java b/lib/src/main/java/io/v/impl/google/lib/discovery/VDiscoveryImpl.java
new file mode 100644
index 0000000..82ae397
--- /dev/null
+++ b/lib/src/main/java/io/v/impl/google/lib/discovery/VDiscoveryImpl.java
@@ -0,0 +1,36 @@
+package io.v.impl.google.lib.discovery;
+
+import java.util.List;
+
+import io.v.v23.context.VContext;
+import io.v.v23.discovery.Service;
+import io.v.v23.discovery.VDiscovery;
+import io.v.v23.security.BlessingPattern;
+import io.v.v23.verror.VException;
+
+/**
+ * Implements the {@link VDiscovery} interface
+ */
+public class VDiscoveryImpl implements VDiscovery{
+    private long nativeDiscovery;
+    private long nativeTrigger;
+
+    private native void nativeDelete(long discovery, long trigger);
+
+    private VDiscoveryImpl(long nativeDiscovery, long nativeTrigger) {
+        this.nativeDiscovery = nativeDiscovery;
+        this.nativeTrigger = nativeTrigger;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        nativeDelete(nativeDiscovery, nativeTrigger);
+    }
+
+    @Override
+    public native void advertise(VContext ctx, Service service, List<BlessingPattern> patterns, DoneCallback cb);
+
+    @Override
+    public native void scan(VContext ctx, String query, UpdateCallback updateCallback);
+}
diff --git a/lib/src/main/java/io/v/impl/google/rt/VRuntimeImpl.java b/lib/src/main/java/io/v/impl/google/rt/VRuntimeImpl.java
index aec7cb5..37b8849 100644
--- a/lib/src/main/java/io/v/impl/google/rt/VRuntimeImpl.java
+++ b/lib/src/main/java/io/v/impl/google/rt/VRuntimeImpl.java
@@ -7,6 +7,7 @@
 import io.v.v23.Options;
 import io.v.v23.VRuntime;
 import io.v.v23.context.VContext;
+import io.v.v23.discovery.VDiscovery;
 import io.v.v23.namespace.Namespace;
 import io.v.v23.rpc.Client;
 import io.v.v23.rpc.Dispatcher;
@@ -41,6 +42,8 @@
             throws VException;
     private static native ListenSpec nativeGetListenSpec(VContext ctx) throws VException;
 
+    private static native VDiscovery nativeGetDiscovery(VContext ctx) throws VException;
+
     // Attaches a server to the given context.  Used by this class and other classes
     // that natively create a server.
     private static VContext withServer(VContext ctx, Server server) {
@@ -126,6 +129,15 @@
             throw new RuntimeException("Couldn't get listen spec: ", e);
         }
     }
+
+    @Override
+    public VDiscovery getDiscovery(VContext ctx) {
+        try {
+            return nativeGetDiscovery(ctx);
+        } catch (VException e) {
+            throw new RuntimeException("Couldn't get discovery: ", e);
+        }
+    }
     @Override
     public VContext getContext() {
         return this.ctx;
diff --git a/lib/src/main/java/io/v/v23/V.java b/lib/src/main/java/io/v/v23/V.java
index 464825e..9a7fe88 100644
--- a/lib/src/main/java/io/v/v23/V.java
+++ b/lib/src/main/java/io/v/v23/V.java
@@ -17,6 +17,7 @@
 
 import io.v.impl.google.rt.VRuntimeImpl;
 import io.v.v23.context.VContext;
+import io.v.v23.discovery.VDiscovery;
 import io.v.v23.namespace.Namespace;
 import io.v.v23.rpc.Client;
 import io.v.v23.rpc.Dispatcher;
@@ -452,5 +453,9 @@
         return runtime;
     }
 
+    public static VDiscovery getDiscovery(VContext ctx) {
+        return getRuntime().getDiscovery(ctx);
+    }
+
     protected V() {}
 }
diff --git a/lib/src/main/java/io/v/v23/VRuntime.java b/lib/src/main/java/io/v/v23/VRuntime.java
index 11cb914..cb1f95b 100644
--- a/lib/src/main/java/io/v/v23/VRuntime.java
+++ b/lib/src/main/java/io/v/v23/VRuntime.java
@@ -5,6 +5,7 @@
 package io.v.v23;
 
 import io.v.v23.context.VContext;
+import io.v.v23.discovery.VDiscovery;
 import io.v.v23.namespace.Namespace;
 import io.v.v23.rpc.Client;
 import io.v.v23.rpc.Dispatcher;
@@ -193,6 +194,8 @@
      */
     VContext getContext();
 
+    VDiscovery getDiscovery(VContext ctx);
+
     /**
      * Shuts down the runtime, allowing the runtime to release resources, shutdown services and
      * the like.
diff --git a/lib/src/main/java/io/v/v23/discovery/VDiscovery.java b/lib/src/main/java/io/v/v23/discovery/VDiscovery.java
new file mode 100644
index 0000000..868238b
--- /dev/null
+++ b/lib/src/main/java/io/v/v23/discovery/VDiscovery.java
@@ -0,0 +1,31 @@
+package io.v.v23.discovery;
+
+import java.util.List;
+
+import io.v.impl.google.lib.discovery.ScanHandler;
+import io.v.v23.context.VContext;
+import io.v.v23.security.BlessingPattern;
+
+/**
+ * An interface that exposes the Vanadium Discovery Api.
+ */
+public interface VDiscovery {
+    interface DoneCallback {
+        /**
+         * Called when the advertisement or scan finishes.
+         */
+        void done();
+    }
+
+    interface UpdateCallback {
+        /**
+         * Called when a new update for a Service that matches the scan query.
+         * @param update
+         */
+        void handleUpdate(Update update);
+    }
+
+    void advertise(VContext ctx, Service service, List<BlessingPattern> patterns, DoneCallback cb);
+
+    void scan(VContext ctx, String query, UpdateCallback updateCb);
+}
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
index 7ea8bc7..b3c0479 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/DeviceCacheTest.java
@@ -17,7 +17,7 @@
 import io.v.x.ref.lib.discovery.Uuid;
 
 /**
- * Testis for {@link DeviceCache}.
+ * Tests for {@link DeviceCache}.
  */
 public class DeviceCacheTest extends TestCase {
     private abstract class CountingHandler implements ScanHandler {
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
index 7f2c6cf..0c135ca 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/EncodingUtilTest.java
@@ -4,10 +4,10 @@
 
 package io.v.impl.google.lib.discovery;
 
-
 import junit.framework.TestCase;
 
 import java.io.IOException;
+
 import java.util.Arrays;
 
 import io.v.x.ref.lib.discovery.EncryptionAlgorithm;
diff --git a/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java b/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
index f28ea48..f59c3cd 100644
--- a/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
+++ b/lib/src/test/java/io/v/impl/google/lib/discovery/UUIDUtilTest.java
@@ -14,7 +14,11 @@
 import io.v.x.ref.lib.discovery.testdata.UuidTestData;
 
 /**
+<<<<<<< HEAD
+ * Tests for {@link UUIDUtil}
+=======
  * Tests for {@link UUIDUtil}.
+>>>>>>> ble
  */
 public class UUIDUtilTest extends TestCase {
     public void testInterfaceNameUUID() {
diff --git a/projects/discovery_sample/gradlew.bat b/projects/discovery_sample/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/projects/discovery_sample/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega