Skip to content
This repository has been archived by the owner on Oct 1, 2018. It is now read-only.

Commit

Permalink
Fix for #18 on Android platform.
Browse files Browse the repository at this point in the history
  • Loading branch information
nikDemyankov committed Dec 17, 2015
1 parent 27529ea commit 99ab30a
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 39 deletions.
117 changes: 85 additions & 32 deletions src/android/com/nordnetab/cordova/ul/UniversalLinksPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.nordnetab.cordova.ul.js.JSAction;
Expand All @@ -17,7 +18,10 @@
import org.apache.cordova.PluginResult;
import org.json.JSONException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Created by Nikolay Demyankov on 09.09.15.
Expand All @@ -30,9 +34,10 @@ public class UniversalLinksPlugin extends CordovaPlugin {
// list of hosts, defined in config.xml
private List<ULHost> supportedHosts;

// callback through which we will send events to JS
private CallbackContext defaultCallback;
// list of subscribers
private Map<String, CallbackContext> subscribers;

// stored message, that is captured on application launch
private JSMessage storedMessage;

// region Public API
Expand All @@ -42,13 +47,21 @@ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);

supportedHosts = new ULConfigXmlParser(cordova.getActivity()).parse();

if (subscribers == null) {
subscribers = new HashMap<String, CallbackContext>();
}

handleIntent(cordova.getActivity().getIntent());
}

@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
boolean isHandled = true;
if (JSAction.INIT.equals(action)) {
initJS(callbackContext);
if (JSAction.SUBSCRIBE.equals(action)) {
subscribeForEvent(args, callbackContext);
} else if (JSAction.UNSUBSCRIBE.equals(action)) {
unsubscribeFromEvent(args);
} else {
isHandled = false;
}
Expand All @@ -66,41 +79,86 @@ public void onNewIntent(Intent intent) {
// region JavaScript methods

/**
* Initialize plugin to communicate with JavaScript side.
* Add subscriber for the event.
*
* @param callback default JS callback
* @param arguments arguments, passed from JS side
* @param callbackContext callback to use when event is captured
*/
private void initJS(CallbackContext callback) {
setDefaultCallback(callback);
if (storedMessage != null) {
sendMessageToJs(storedMessage);
storedMessage = null;
private void subscribeForEvent(final CordovaArgs arguments, final CallbackContext callbackContext) {
final String eventName = getEventNameFromArguments(arguments);
if (TextUtils.isEmpty(eventName)) {
return;
}

handleIntent(cordova.getActivity().getIntent());
subscribers.put(eventName, callbackContext);
tryToConsumeEvent();
}

private void setDefaultCallback(CallbackContext callback) {
this.defaultCallback = callback;
/**
* Remove subscriber from the event.
*
* @param arguments arguments, passed from JS side
*/
private void unsubscribeFromEvent(final CordovaArgs arguments) {
if (subscribers.size() == 0) {
return;
}

final String eventName = getEventNameFromArguments(arguments);
if (TextUtils.isEmpty(eventName)) {
return;
}

subscribers.remove(eventName);
}

/**
* Send message to JS side.
* Get event name from the cordova arguments.
*
* @param message message to send
* @return true - if message is sent; otherwise - false
* @param arguments received arguments
* @return event name; <code>null</code> if non is found
*/
private String getEventNameFromArguments(final CordovaArgs arguments) {
String eventName = null;
try {
eventName = arguments.getString(0);
} catch (JSONException e) {
Log.d("UniversalLinks", "Failed to get event name from the JS arguments", e);
}

return eventName;
}

/**
* Try to send event to the subscribers.
*/
private boolean sendMessageToJs(JSMessage message) {
if (defaultCallback == null) {
return false;
private void tryToConsumeEvent() {
if (subscribers.size() == 0 || storedMessage == null) {
return;
}

final String storedEventName = storedMessage.getEventName();
final Set<Map.Entry<String, CallbackContext>> subscribersSet = subscribers.entrySet();
for (Map.Entry<String, CallbackContext> subscriber : subscribersSet) {
final String eventName = subscriber.getKey();
if (eventName.equals(storedEventName)) {
sendMessageToJs(storedMessage, subscriber.getValue());
storedMessage = null;
break;
}
}
}

/**
* Send message to JS side.
*
* @param message message to send
* @param callback to what callback we are sending the message
*/
private void sendMessageToJs(JSMessage message, CallbackContext callback) {
final PluginResult result = new PluginResult(PluginResult.Status.OK, message);
result.setKeepCallback(true);
defaultCallback.sendPluginResult(result);

return true;
callback.sendPluginResult(result);
}

// endregion
Expand Down Expand Up @@ -130,18 +188,13 @@ private void handleIntent(Intent intent) {
// try to find host in the hosts list from the config.xml
ULHost host = findHostByUrl(launchUri);
if (host == null) {
Log.d("CUL", "Host " + launchUri.getHost() + " is not supported");
Log.d("UniversalLinks", "Host " + launchUri.getHost() + " is not supported");
return;
}

// send message to the JS side;
// if callback is not yet initialized - store message for later use;
final JSMessage message = new JSMessage(host, launchUri);
if (!sendMessageToJs(message)) {
storedMessage = message;
} else {
storedMessage = null;
}
// store message and try to consume it
storedMessage = new JSMessage(host, launchUri);
tryToConsumeEvent();
}

/**
Expand Down
8 changes: 6 additions & 2 deletions src/android/com/nordnetab/cordova/ul/js/JSAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
public final class JSAction {

/**
* Initialize native side to work with JS
* Subscribe to event.
*/
public static final String INIT = "jsInitPlugin";
public static final String SUBSCRIBE = "jsSubscribeForEvent";

/**
* Unsubscribe from event.
*/
public static final String UNSUBSCRIBE = "jsUnsubscribeFromEvent";
}
20 changes: 16 additions & 4 deletions src/android/com/nordnetab/cordova/ul/model/JSMessage.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.nordnetab.cordova.ul.model;

import android.net.Uri;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -62,6 +63,8 @@ private static final class JSDataKeys {
public static final String ORIGIN = "url";
}

private String eventName;

/**
* Constructor
*
Expand All @@ -73,18 +76,27 @@ public JSMessage(ULHost host, Uri originalUri) {
setMessageData(host, originalUri);
}

/**
* Getter for event name of this message.
*
* @return event name
*/
public String getEventName() {
return eventName;
}

// region Event name setters

/**
* Set event name for this message entry.
*/
private void setEventName(ULHost host, Uri originalUri) {
final String event = getEventName(host, originalUri);
eventName = getEventName(host, originalUri);

try {
put(JSGeneralKeys.EVENT, event);
put(JSGeneralKeys.EVENT, eventName);
} catch (JSONException e) {
e.printStackTrace();
Log.d("UniversalLinks", "Failed to set event name", e);
}
}

Expand Down Expand Up @@ -129,7 +141,7 @@ private void setMessageData(ULHost host, Uri originalUri) {

put(JSGeneralKeys.DATA, dataObject);
} catch (JSONException e) {
e.printStackTrace();
Log.d("UniversalLinks", "Failed to set event data", e);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/android/com/nordnetab/cordova/ul/model/ULHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
public class ULHost {

// default event name, that is dispatched to JS if none was set to the host or path
private static final String DEFAULT_EVENT = "ul_didLaunchAppFromLink";
private static final String DEFAULT_EVENT = "didLaunchAppFromLink";

// default scheme for the host
private static final String DEFAULT_SCHEME = "http";
Expand Down

0 comments on commit 99ab30a

Please sign in to comment.