diff --git a/README.md b/README.md
index 9698e3f..f463ee2 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,84 @@
-# Twilio Client Phonegap plugins
+# Twilio Client Phonegap plugins for iOS and Android (version 1.0.7)
-This is a Phonegap plugin that exposes the same JS API as Twilio Client for web as much as possible, meaning you should be able to use the same Twilio Client code from your web application inside of your Phonegap application with few if any modifications.
+These are Phonegap plugins that expose the same JS API as Twilio Client for web as much as possible, meaning you should be able to use the same Twilio Client code from your web application inside of your Phonegap application with few if any modifications.
+
+# Latest versions tested with this plugin
+#### (as of August 16, 2016)
+- Cordova 6.3.1
+- Cordova Android 5.2.1
+- Cordova iOS 4.1.0
+- Twilio Client for iOS 1.2.8
+- Twilio Client for Android 1.2.17
+- XCode 7.3
+- Android SDK 23
+
+# Android Gradle Support
+- Version 1.0.6 and above now downloads the latest version of the Twilio SDK from jcenter - you will need to use the Cordova Android plugin 5.2.1 for this, as the version of Gradle needed is 2.1.3, and 5.2.1 also includes jcenter as a default repository.
+
+# Android Support Library
+- Versions 1.0.4 and earlier of the plugin required you to include the Android support library v4 in the lib. Cordova now has a solution for requiring Android libs through Gradle dependencies. This will save you a step on installation, as well as making this plugin (as of versin 1.0.5) compatible with other plugins such as the PhoneGap Push plugin. One handy tip I found on that plugin is that you may need to update your Android support library using this command line tool, if you get an error saying that the Android Support v4 library can not be found:
+
+`android update sdk --no-ui --filter "extra"`
+
+Please file an issue if you have problems with the Android support library or any compatibility issues with other plugins.
+
+# Example application
+https://github.com/jefflinwood/TwilioClientPhoneGapExampleApp
+
+# PhoneGap/Cordova Overview
+
+- Install the most recent version of Cordova (as of this writing, 6.3.1 tools - http://http://cordova.apache.org/
+- Install plugman - https://github.com/apache/cordova-plugman
+
+# Both Platforms at once
##Instructions
+```
+cordova plugin add https://github.com/jefflinwood/twilio_client_phonegap.git
+```
+
+# iOS only
+
+##Instructions
+
+```
+ plugman install --platform ios --project platforms/ios --plugin https://github.com/jefflinwood/twilio_client_phonegap.git
+
+```
-- Follow the directions to create a new PhoneGap/Cordova iOS application.
-- Follow the instructions in the Twilio iOS client quickstart, e.g. copy headers and static lib into your xcode project, link required frameworks, linker flags, etc.
+- After installing the Twilio Client plugin, you will need to download and install the Twilio Client SDK for iOS - follow the directions provided after plugman finishes.
-- Copy the Objective-C files into the `plugins` directory of your Phonegap project, and the JavaScript file into the `www` directory.
+# Android only
+
+## Instructions
+
+```
+plugman install --platform android --project platforms/android --plugin https://github.com/jefflinwood/twilio_client_phonegap.git
+
+```
+
+## Additional Features
+
+In addition to the standard features of the Twilio Client JS Library, you can also use the included showNotification and cancelNotification functions to display a UILocalNotifcation to the user when during an incoming call while the app is running in the background:
+
+```javascript
+Twilio.Connection.showNotification("Notification Text", "notification_sound.wav");
+```
+
+```javascript
+Twilio.Connection.cancelNotification();
+```
+
+You can also turn the device's speaker phone on or off during a call using the following method:
+
+```javascript
+Twilio.Connection.setSpeaker("on");
+```
-- Add a new plugin XML item in config.xml:
-
-
-
+## Changelog
+- 1.0.7 - Added Marshmallow/SDK 23 support for runtime permissions
+- 1.0.6 - Updated Android platform for plugin to pull in Twilio Android SDK using Gradle
## Limitations
diff --git a/iOS/TCPlugin.m b/iOS/TCPlugin.m
deleted file mode 100644
index 0360734..0000000
--- a/iOS/TCPlugin.m
+++ /dev/null
@@ -1,191 +0,0 @@
-//
-// TCPlugin.h
-// Twilio Client plugin for PhoneGap
-//
-// Copyright 2012 Stevie Graham.
-//
-
-#import "TCPlugin.h"
-
-@interface TCPlugin() {
- TCDevice *_device;
- TCConnection *_connection;
- NSString *_callback;
-}
-
-@property(nonatomic, strong) TCDevice *device;
-@property(nonatomic, strong) NSString *callback;
-@property(atomic, strong) TCConnection *connection;
-
--(void)javascriptCallback:(NSString *)event;
--(void)javascriptCallback:(NSString *)event withArguments:(NSDictionary *)arguments;
--(void)javascriptErrorback:(NSError *)error;
-
-@end
-
-@implementation TCPlugin
-
-@synthesize device = _device;
-@synthesize callback = _callback;
-@synthesize connection = _connection;
-
-# pragma mark device delegate method
-
--(void)device:(TCDevice *)device didStopListeningForIncomingConnections:(NSError *)error {
- [self javascriptErrorback:error];
-}
-
--(void)device:(TCDevice *)device didReceiveIncomingConnection:(TCConnection *)connection {
- [self javascriptCallback:@"onincoming"];
-}
-
--(void)device:(TCDevice *)device didReceivePresenceUpdate:(TCPresenceEvent *)presenceEvent {
- NSString *available = [NSString stringWithFormat:@"%d", presenceEvent.isAvailable];
- NSDictionary *object = [NSDictionary dictionaryWithObjectsAndKeys:presenceEvent.name, @"from", available, @"available", nil];
- [self javascriptCallback:@"onpresence" withArguments:object];
-}
-
--(void)deviceDidStartListeningForIncomingConnections:(TCDevice *)device {
- // What to do here? The JS library doesn't have an event for this.
-}
-
-# pragma mark connection delegate methods
-
--(void)connection:(TCConnection*)connection didFailWithError:(NSError*)error {
- [self javascriptErrorback:error];
-}
-
--(void)connectionDidStartConnecting:(TCConnection*)connection {
- self.connection = connection;
- // What to do here? The JS library doesn't have an event for connection negotiation.
-}
-
--(void)connectionDidConnect:(TCConnection*)connection {
- self.connection = connection;
- [self javascriptCallback:@"onconnect"];
- if([connection isIncoming]) [self javascriptCallback:@"onaccept"];
-}
-
--(void)connectionDidDisconnect:(TCConnection*)connection {
- self.connection = connection;
- [self javascriptCallback:@"ondevicedisconnect"];
- [self javascriptCallback:@"onconnectiondisconnect"];
-}
-
-# pragma mark javascript device mapper methods
-
--(void)deviceSetup:(NSMutableArray *)arguments withDict:(NSMutableDictionary*)options {
- self.callback = [arguments pop];
- self.device = [[TCDevice alloc] initWithCapabilityToken:[arguments pop] delegate:self];
-
- // Disable sounds. was getting EXC_BAD_ACCESS
- self.device.incomingSoundEnabled = NO;
- self.device.outgoingSoundEnabled = NO;
- self.device.disconnectSoundEnabled = NO;
-
- [self javascriptCallback:@"onready"];
-}
-
--(void)connect:(NSArray *)arguments withDict:(NSMutableDictionary *)options {
- [self.device connect:options delegate:self];
-}
-
--(void)disconnectAll:(NSArray *)arguments withDict:(NSMutableDictionary *)options {
- [self.device disconnectAll];
-}
-
--(void)deviceStatus:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options {
- NSString *state;
- switch ([self.device state]) {
- case TCDeviceStateBusy:
- state = @"busy";
- break;
-
- case TCDeviceStateReady:
- state = @"ready";
- break;
-
- case TCDeviceStateOffline:
- state = @"offline";
- break;
-
- default:
- break;
- }
-
- CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:state];
- [self performSelectorOnMainThread:@selector(writeJavascript:) withObject:[result toSuccessCallbackString:[arguments pop]] waitUntilDone:NO];
-}
-
-
-# pragma mark javascript connection mapper methods
-
--(void)acceptConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options {
- [self.connection accept];
-}
-
--(void)disconnectConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options {
- [self.connection disconnect];
-}
-
--(void)muteConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options {
- if(self.connection.isMuted) {
- self.connection.muted = NO;
- } else {
- self.connection.muted = YES;
- }
-}
-
--(void)sendDigits:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options {
- [self.connection sendDigits:[arguments pop]];
-}
-
--(void)connectionStatus:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options {
- NSString *state;
- switch ([self.connection state]) {
- case TCConnectionStateConnected:
- state = @"open";
- break;
-
- case TCConnectionStateConnecting:
- state = @"connecting";
- break;
-
- case TCConnectionStatePending:
- state = @"pending";
- break;
-
- case TCConnectionStateDisconnected:
- state = @"closed";
-
- default:
- break;
- }
-
- CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:state];
- [self performSelectorOnMainThread:@selector(writeJavascript:) withObject:[result toSuccessCallbackString:[arguments pop]] waitUntilDone:NO];
-}
-
-# pragma mark private methods
-
--(void)javascriptCallback:(NSString *)event withArguments:(NSDictionary *)arguments {
- NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:event, @"callback", arguments, @"arguments", nil];
- CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:options];
- result.keepCallback = [NSNumber numberWithBool:YES];
-
- [self performSelectorOnMainThread:@selector(writeJavascript:) withObject:[result toSuccessCallbackString:self.callback] waitUntilDone:NO];
-}
-
--(void)javascriptCallback:(NSString *)event {
- [self javascriptCallback:event withArguments:nil];
-}
-
--(void)javascriptErrorback:(NSError *)error {
- NSDictionary *object = [NSDictionary dictionaryWithObjectsAndKeys:[error localizedDescription], @"message", nil];
- CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:object];
- result.keepCallback = [NSNumber numberWithBool:YES];
-
- [self performSelectorOnMainThread:@selector(writeJavascript:) withObject:[result toErrorCallbackString:self.callback] waitUntilDone:NO];
-}
-
-@end
\ No newline at end of file
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..7fa4a9e
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,78 @@
+
+
+
+ TwilioClient
+ Use the native Twilio Client for iOS or Android with Cordova/PhoneGap and the Twilio Client JavaScript API
+ Stevie Graham/Lyle Pratt/Jeff Linwood
+ Apache
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ voip
+ audio
+
+
+
+
+
+
+
+
+
+
+
+
+
+You need to download __Twilio Client for iOS__ from https://www.twilio.com/docs/client/ios. Uncompress the download - you will need to follow a few steps that plugman can not do yet:
+
+* Add the Twilio Client static libraries (the .a files in the Libraries folder) to your Xcode project
+
+* Add the Twilio Client headers files (the .h files in the Headers folder) to your Xcode project
+
+
+
diff --git a/src/android/com/phonegap/plugins/twilioclient/IncomingConnectionActivity.java b/src/android/com/phonegap/plugins/twilioclient/IncomingConnectionActivity.java
new file mode 100644
index 0000000..ad2bdff
--- /dev/null
+++ b/src/android/com/phonegap/plugins/twilioclient/IncomingConnectionActivity.java
@@ -0,0 +1,41 @@
+package com.phonegap.plugins.twilioclient;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+
+//import com.twilio.client.Connection;
+//import com.twilio.client.Device;
+
+/**
+ *
+ * Class based on Twilio Android documentation on handling incoming calls with intents
+ *
+ */
+
+public class IncomingConnectionActivity extends Activity {
+
+ public static final String ACTION_NAME = "INCOMING_CONNECTION";
+ @Override
+ public void onNewIntent(Intent intent)
+ {
+ Log.d("TCPlugin", "ON NEW INTENT IN CONNECTION ACTIVITY");
+ super.onNewIntent(intent);
+ setIntent(intent);
+ }
+
+ @Override
+ public void onResume()
+ {
+ Log.d("TCPlugin", "ON RESUME IN CONNECTION ACTIVITY");
+ super.onResume();
+ Intent intent = getIntent();
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+ intent.setAction(ACTION_NAME);
+ lbm.sendBroadcast(intent);
+ finish();
+ }
+
+
+}
diff --git a/src/android/com/phonegap/plugins/twilioclient/TCPlugin.java b/src/android/com/phonegap/plugins/twilioclient/TCPlugin.java
new file mode 100644
index 0000000..4feb85a
--- /dev/null
+++ b/src/android/com/phonegap/plugins/twilioclient/TCPlugin.java
@@ -0,0 +1,609 @@
+package com.phonegap.plugins.twilioclient;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.media.AudioManager;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+
+import com.twilio.client.Connection;
+import com.twilio.client.ConnectionListener;
+import com.twilio.client.Device;
+import com.twilio.client.DeviceListener;
+import com.twilio.client.PresenceEvent;
+import com.twilio.client.Twilio;
+import com.twilio.client.Twilio.InitListener;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.apache.cordova.PluginResult.Status;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+//import android.R;
+
+/**
+ * Twilio Client Plugin for Cordova/PhoneGap Targeted at version 2.9 for
+ * compatibility
+ *
+ *
+ *
+ * @see https://github.com/stevegraham/twilio_client_phonegap
+ * @author Jeff Linwood, https://github.com/jefflinwood
+ *
+ */
+public class TCPlugin extends CordovaPlugin implements DeviceListener,
+ InitListener, ConnectionListener {
+
+ private final static String TAG = "TCPlugin";
+
+ private Device mDevice;
+ private Connection mConnection;
+ private CallbackContext mInitCallbackContext;
+ private JSONArray mInitDeviceSetupArgs;
+ private int mCurrentNotificationId = 1;
+ private String mCurrentNotificationText;
+ private TCPlugin plugin = this;
+
+ // Marshmallow Permissions
+ public static final String RECORD_AUDIO = Manifest.permission.RECORD_AUDIO;
+ public static final int RECORD_AUDIO_REQ_CODE = 0;
+
+
+
+ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // mDevice = intent.getParcelableExtra(Device.EXTRA_DEVICE);
+ mConnection = intent.getParcelableExtra(Device.EXTRA_CONNECTION);
+ mConnection.setConnectionListener(plugin);
+ Log.d(TAG, "incoming intent received with connection: "+ mConnection.getState().name());
+ String constate = mConnection.getState().name();
+ if(constate.equals("PENDING")) {
+ TCPlugin.this.javascriptCallback("onincoming", mInitCallbackContext);
+ }
+ }
+ };
+
+ /**
+ * Android Cordova Action Router
+ *
+ * Executes the request.
+ *
+ * This method is called from the WebView thread. To do a non-trivial amount
+ * of work, use: cordova.getThreadPool().execute(runnable);
+ *
+ * To run on the UI thread, use:
+ * cordova.getActivity().runOnUiThread(runnable);
+ *
+ * @param action
+ * The action to execute.
+ * @param args
+ * The exec() arguments in JSON form.
+ * @param callbackContext
+ * The callback context used when calling back into JavaScript.
+ * @return Whether the action was valid.
+ */
+ @Override
+ public boolean execute(final String action, final JSONArray args,
+ final CallbackContext callbackContext) throws JSONException {
+ if ("deviceSetup".equals(action)) {
+ if (Twilio.isInitialized()) {
+ deviceSetup(args, callbackContext);
+ } else {
+ mInitCallbackContext = callbackContext;
+ mInitDeviceSetupArgs = args;
+ if(cordova.hasPermission(RECORD_AUDIO))
+ {
+ initTwilio(callbackContext);
+ }
+ else
+ {
+ cordova.requestPermission(this, RECORD_AUDIO_REQ_CODE, RECORD_AUDIO);
+ }
+
+
+ }
+ return true;
+
+ } else if ("connect".equals(action)) {
+ connect(args, callbackContext);
+ return true;
+ } else if ("disconnectAll".equals(action)) {
+ disconnectAll(args, callbackContext);
+ return true;
+ } else if ("acceptConnection".equals(action)) {
+ acceptConnection(args, callbackContext);
+ return true;
+ } else if ("disconnectConnection".equals(action)) {
+ disconnectConnection(args, callbackContext);
+ return true;
+ } else if ("sendDigits".equals(action)) {
+ sendDigits(args, callbackContext);
+ return true;
+ } else if ("muteConnection".equals(action)) {
+ muteConnection(callbackContext);
+ return true;
+ } else if ("deviceStatus".equals(action)) {
+ deviceStatus(callbackContext);
+ return true;
+ } else if ("connectionStatus".equals(action)) {
+ connectionStatus(callbackContext);
+ return true;
+ } else if ("connectionParameters".equals(action)) {
+ connectionParameters(callbackContext);
+ return true;
+ } else if ("rejectConnection".equals(action)) {
+ rejectConnection(args, callbackContext);
+ return true;
+ } else if ("showNotification".equals(action)) {
+ showNotification(args,callbackContext);
+ return true;
+ } else if ("cancelNotification".equals(action)) {
+ cancelNotification(args,callbackContext);
+ return true;
+ } else if ("setSpeaker".equals(action)) {
+ setSpeaker(args,callbackContext);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Initialize Twilio's client library - this is only necessary on Android,
+ *
+ */
+ private void initTwilio(CallbackContext callbackContext) {
+ Twilio.initialize(cordova.getActivity().getApplicationContext(), this);
+ }
+
+ /**
+ * Set up the Twilio device with a capability token
+ *
+ * @param arguments JSONArray with a Twilio capability token
+ */
+ private void deviceSetup(JSONArray arguments,
+ final CallbackContext callbackContext) {
+ if (arguments == null || arguments.length() < 1) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ if (arguments.optString(0).equals("")) {
+ Log.d("TCPlugin","Releasing device");
+ cordova.getThreadPool().execute(new Runnable(){
+ public void run() {
+ mDevice.release();
+ }
+ });
+ javascriptCallback("onoffline", callbackContext);
+ return;
+ }
+ mDevice = Twilio.createDevice(arguments.optString(0), this);
+
+ Intent intent = new Intent(this.cordova.getActivity(), IncomingConnectionActivity.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this.cordova.getActivity(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ mDevice.setIncomingIntent(pendingIntent);
+
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(cordova.getActivity());
+ lbm.registerReceiver(mBroadcastReceiver, new IntentFilter(IncomingConnectionActivity.ACTION_NAME));
+
+ // delay one second to give Twilio device a change to change status (similar to iOS plugin)
+ cordova.getThreadPool().execute(new Runnable(){
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ deviceStatusEvent(callbackContext);
+ } catch (InterruptedException ex) {
+ Log.e(TAG,"InterruptedException: " + ex.getMessage(),ex);
+ }
+ }
+ });
+ }
+
+ private void deviceStatusEvent(CallbackContext callbackContext) {
+ if (mDevice == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ switch (mDevice.getState()) {
+ case OFFLINE:
+ javascriptCallback("onoffline", callbackContext);
+ break;
+ case READY:
+ javascriptCallback("onready", callbackContext);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void connect(JSONArray arguments, CallbackContext callbackContext) {
+ JSONObject options = arguments.optJSONObject(0);
+ Map map = getMap(options);
+ mConnection = mDevice.connect(map, this);
+ Log.d(TAG, "Twilio device.connect() called: "
+ + mConnection.getState().name());
+ }
+
+ // helper method to get a map of strings from a JSONObject
+ public Map getMap(JSONObject object) {
+ if (object == null) {
+ return null;
+ }
+
+ Map map = new HashMap();
+
+ @SuppressWarnings("rawtypes")
+ Iterator keys = object.keys();
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+ map.put(key, object.optString(key));
+ }
+ return map;
+ }
+
+ // helper method to get a JSONObject from a Map of Strings
+ public JSONObject getJSONObject(Map map) throws JSONException {
+ if (map == null) {
+ return null;
+ }
+
+ JSONObject json = new JSONObject();
+ for (String key : map.keySet()) {
+ json.putOpt(key, map.get(key));
+ }
+ return json;
+ }
+
+ private void disconnectAll(JSONArray arguments, CallbackContext callbackContext) {
+ mDevice.disconnectAll();
+ callbackContext.success();
+ }
+
+ private void acceptConnection(JSONArray arguments, CallbackContext callbackContext) {
+ mConnection.accept();
+ callbackContext.success();
+ }
+
+ private void rejectConnection(JSONArray arguments, CallbackContext callbackContext) {
+ mConnection.reject();
+ callbackContext.success();
+ }
+
+ private void disconnectConnection(JSONArray arguments, CallbackContext callbackContext) {
+ mConnection.disconnect();
+ callbackContext.success();
+ }
+
+ private void sendDigits(JSONArray arguments,
+ CallbackContext callbackContext) {
+ if (arguments == null || arguments.length() < 1 || mConnection == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ mConnection.sendDigits(arguments.optString(0));
+ }
+
+ private void muteConnection(CallbackContext callbackContext) {
+ if (mConnection == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ mConnection.setMuted(!mConnection.isMuted());
+ callbackContext.success();
+ }
+
+
+ private void deviceStatus(CallbackContext callbackContext) {
+ if (mDevice == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ String state = "";
+ switch (mDevice.getState()) {
+ case BUSY:
+ state = "busy";
+ break;
+ case OFFLINE:
+ state = "offline";
+ break;
+ case READY:
+ state = "ready";
+ break;
+ default:
+ break;
+ }
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK,state);
+ callbackContext.sendPluginResult(result);
+ }
+
+
+ private void connectionStatus(CallbackContext callbackContext) {
+ if (mConnection == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+ String state = "";
+ switch (mConnection.getState()) {
+ case CONNECTED:
+ state = "open";
+ break;
+ case CONNECTING:
+ state = "connecting";
+ break;
+ case DISCONNECTED:
+ state = "closed";
+ break;
+ case PENDING:
+ state = "pending";
+ break;
+ default:
+ break;
+
+ }
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK,state);
+ callbackContext.sendPluginResult(result);
+ }
+
+
+ private void connectionParameters(CallbackContext callbackContext) {
+ if (mConnection == null) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.ERROR));
+ return;
+ }
+
+ JSONObject parameters = new JSONObject(mConnection.getParameters());
+
+
+ PluginResult result = new PluginResult(PluginResult.Status.OK,parameters);
+ callbackContext.sendPluginResult(result);
+ }
+
+
+ private void showNotification(JSONArray arguments, CallbackContext context) {
+ Context acontext = TCPlugin.this.webView.getContext();
+ NotificationManager mNotifyMgr =
+ (NotificationManager) acontext.getSystemService(Activity.NOTIFICATION_SERVICE);
+ mNotifyMgr.cancelAll();
+ mCurrentNotificationText = arguments.optString(0);
+
+
+ PackageManager pm = acontext.getPackageManager();
+ Intent notificationIntent = pm.getLaunchIntentForPackage(acontext.getPackageName());
+ notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ notificationIntent.putExtra("notificationTag", "BVNotification");
+
+ PendingIntent pendingIntent = PendingIntent.getActivity(acontext, 0, notificationIntent, 0);
+ int notification_icon = acontext.getResources().getIdentifier("notification", "drawable", acontext.getPackageName());
+ NotificationCompat.Builder mBuilder =
+ new NotificationCompat.Builder(acontext)
+ .setSmallIcon(notification_icon)
+ .setContentTitle("Incoming Call")
+ .setContentText(mCurrentNotificationText)
+ .setContentIntent(pendingIntent);
+ mNotifyMgr.notify(mCurrentNotificationId, mBuilder.build());
+
+ context.success();
+ }
+
+ private void cancelNotification(JSONArray arguments, CallbackContext context) {
+ NotificationManager mNotifyMgr =
+ (NotificationManager) TCPlugin.this.webView.getContext().getSystemService(Activity.NOTIFICATION_SERVICE);
+ mNotifyMgr.cancel(mCurrentNotificationId);
+ context.success();
+ }
+
+ /**
+ * Changes sound from earpiece to speaker and back
+ *
+ * @param mode Speaker Mode
+ * */
+ public void setSpeaker(JSONArray arguments, final CallbackContext callbackContext) {
+ Context context = cordova.getActivity().getApplicationContext();
+ AudioManager m_amAudioManager;
+ m_amAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ String mode = arguments.optString(0);
+ if(mode.equals("on")) {
+ Log.d("TCPlugin", "SPEAKER");
+ m_amAudioManager.setMode(AudioManager.MODE_NORMAL);
+ m_amAudioManager.setSpeakerphoneOn(true);
+ }
+ else {
+ Log.d("TCPlugin", "EARPIECE");
+ m_amAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ m_amAudioManager.setSpeakerphoneOn(false);
+ }
+ }
+
+ // DeviceListener methods
+
+ @Override
+ public void onPresenceChanged(Device device, PresenceEvent presenceEvent) {
+
+ JSONObject object = new JSONObject();
+ try {
+ object.put("from", presenceEvent.getName());
+ object.put("available",presenceEvent.isAvailable());
+ } catch (JSONException e) {
+ mInitCallbackContext.sendPluginResult(new
+ PluginResult(PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+ javascriptCallback("onpresence", object,mInitCallbackContext);
+
+ }
+
+ @Override
+ public void onStartListening(Device device) {
+ // What to do here? The JS library doesn't have an event for this.
+
+ }
+
+ @Override
+ public void onStopListening(Device device) {
+ // TODO Auto-generated method stub
+ Log.d(TAG, "onStopListening");
+ }
+
+ @Override
+ public void onStopListening(Device device, int errorCode,
+ String errorMessage) {
+ // this.javascriptErrorback(errorCode, errorMessage);
+ Log.d(TAG, "onStopListeningWithError");
+ }
+
+ @Override
+ public boolean receivePresenceEvents(Device device) {
+ return false;
+ }
+
+ // Twilio Init Listener methods
+ @Override
+ public void onError(Exception ex) {
+ Log.e(TAG, "Error Initializing Twilio: " + ex.getMessage(), ex);
+
+ }
+
+ @Override
+ public void onInitialized() {
+ Log.d(TAG, "Twilio Plugin Initialized");
+ deviceSetup(mInitDeviceSetupArgs, mInitCallbackContext);
+ }
+
+ // Twilio Connection Listener methods
+ @Override
+ public void onConnected(Connection connection) {
+ Log.d(TAG, "onConnected()");
+ fireDocumentEvent("onconnect");
+ if (connection.isIncoming()) {
+ fireDocumentEvent("onaccept");
+ }
+
+ }
+
+ @Override
+ public void onConnecting(Connection connection) {
+ Log.d(TAG, "onConnecting()");
+ // What to do here? The JS library doesn't have an event for connection
+ // negotiation.
+
+ }
+
+ @Override
+ public void onDisconnected(Connection connection) {
+ Log.d(TAG, "onDisconnected()");
+ fireDocumentEvent("ondevicedisconnect");
+ fireDocumentEvent("onconnectiondisconnect");
+
+ }
+
+ @Override
+ public void onDisconnected(Connection connection, int errorCode, String errorMessage) {
+ // TODO: Pass error back
+ Log.d(TAG, "onDisconnected(): " + errorMessage);
+ onDisconnected(connection);
+ }
+
+ // Plugin-to-Javascript communication methods
+ private void javascriptCallback(String event, JSONObject arguments,
+ CallbackContext callbackContext) {
+ if (callbackContext == null) {
+ return;
+ }
+ JSONObject options = new JSONObject();
+ try {
+ options.putOpt("callback", event);
+ options.putOpt("arguments", arguments);
+ } catch (JSONException e) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+ PluginResult result = new PluginResult(Status.OK, options);
+ result.setKeepCallback(true);
+ callbackContext.sendPluginResult(result);
+
+ }
+
+ private void javascriptCallback(String event,
+ CallbackContext callbackContext) {
+ javascriptCallback(event, null, callbackContext);
+ }
+
+
+ private void javascriptErrorback(int errorCode, String errorMessage, CallbackContext callbackContext) {
+ JSONObject object = new JSONObject();
+ try {
+ object.putOpt("message", errorMessage);
+ } catch (JSONException e) {
+ callbackContext.sendPluginResult(new PluginResult(
+ PluginResult.Status.JSON_EXCEPTION));
+ return;
+ }
+ PluginResult result = new PluginResult(Status.ERROR, object);
+ result.setKeepCallback(true);
+ callbackContext.sendPluginResult(result);
+ }
+
+ private void fireDocumentEvent(String eventName) {
+ if (eventName != null) {
+ javascriptCallback(eventName,mInitCallbackContext);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ //lifecycle events
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(cordova
+ .getActivity());
+ lbm.unregisterReceiver(mBroadcastReceiver);
+ }
+
+
+ public void onRequestPermissionResult(int requestCode, String[] permissions,
+ int[] grantResults) throws JSONException
+ {
+ for(int r:grantResults)
+ {
+ if(r == PackageManager.PERMISSION_DENIED)
+ {
+ mInitCallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Permission denied"));
+ return;
+ }
+ }
+ switch(requestCode)
+ {
+ case RECORD_AUDIO_REQ_CODE:
+ initTwilio(mInitCallbackContext);
+ break;
+ }
+ }
+
+
+
+}
diff --git a/iOS/TCPlugin.h b/src/ios/TCPlugin.h
similarity index 55%
rename from iOS/TCPlugin.h
rename to src/ios/TCPlugin.h
index 4ac8be6..d4a7be6 100644
--- a/iOS/TCPlugin.h
+++ b/src/ios/TCPlugin.h
@@ -18,22 +18,27 @@
-(void)device:(TCDevice*)device didReceiveIncomingConnection:(TCConnection*)connection;
-(void)device:(TCDevice *)device didReceivePresenceUpdate:(TCPresenceEvent *)presenceEvent;
-(void)deviceDidStartListeningForIncomingConnections:(TCDevice*)device;
--(void)deviceStatus:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options;
+-(void)deviceStatus:(CDVInvokedUrlCommand*)command;
# pragma mark connection delegate methods
-(void)connection:(TCConnection*)connection didFailWithError:(NSError*)error;
-(void)connectionDidStartConnecting:(TCConnection*)connection;
-(void)connectionDidConnect:(TCConnection*)connection;
-(void)connectionDidDisconnect:(TCConnection*)connection;
--(void)connectionStatus:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options;
+-(void)connectionStatus:(CDVInvokedUrlCommand*)command;
+-(void)connectionParameters:(CDVInvokedUrlCommand*)command;
# pragma mark javascript mapper methods
--(void)deviceSetup:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)connect:(NSArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)disconnectAll:(NSArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)acceptConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)disconnectConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)muteConnection:(NSArray *)arguments withDict:(NSMutableDictionary *)options;
--(void)sendDigits:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options;
+-(void)deviceSetup:(CDVInvokedUrlCommand*)command;
+-(void)connect:(CDVInvokedUrlCommand*)command;
+-(void)disconnectAll:(CDVInvokedUrlCommand*)command;
+-(void)acceptConnection:(CDVInvokedUrlCommand*)command;
+-(void)disconnectConnection:(CDVInvokedUrlCommand*)command;
+-(void)rejectConnection:(CDVInvokedUrlCommand*)command;
+-(void)muteConnection:(CDVInvokedUrlCommand*)command;
+-(void)sendDigits:(CDVInvokedUrlCommand*)command;
+-(void)showNotification:(CDVInvokedUrlCommand*)command;
+-(void)cancelNotification:(CDVInvokedUrlCommand*)command;
+-(void)setSpeaker:(CDVInvokedUrlCommand*)command;
@end
\ No newline at end of file
diff --git a/src/ios/TCPlugin.m b/src/ios/TCPlugin.m
new file mode 100644
index 0000000..a43e9f1
--- /dev/null
+++ b/src/ios/TCPlugin.m
@@ -0,0 +1,302 @@
+//
+// TCPlugin.h
+// Twilio Client plugin for PhoneGap / Cordova
+//
+// Copyright 2012 Stevie Graham.
+//
+
+
+#import "TCPlugin.h"
+#import
+
+
+@interface TCPlugin() {
+ TCDevice *_device;
+ TCConnection *_connection;
+ NSString *_callback;
+}
+
+@property(nonatomic, strong) TCDevice *device;
+@property(nonatomic, strong) NSString *callback;
+@property(atomic, strong) TCConnection *connection;
+@property(atomic, strong) UILocalNotification *ringNotification;
+@property(atomic, strong) NSTimer *timer;
+@property (nonatomic, assign) NSInteger *nbRepeats;
+
+-(void)javascriptCallback:(NSString *)event;
+-(void)javascriptCallback:(NSString *)event withArguments:(NSDictionary *)arguments;
+-(void)javascriptErrorback:(NSError *)error;
+
+@end
+
+@implementation TCPlugin
+
+@synthesize device = _device;
+@synthesize callback = _callback;
+@synthesize connection = _connection;
+@synthesize ringNotification = _ringNotification;
+
+
+# pragma mark device delegate method
+
+-(void)device:(TCDevice *)device didStopListeningForIncomingConnections:(NSError *)error {
+ [self javascriptErrorback:error];
+}
+
+-(void)device:(TCDevice *)device didReceiveIncomingConnection:(TCConnection *)connection {
+ self.connection = connection;
+ [self javascriptCallback:@"onincoming"];
+}
+
+-(void)device:(TCDevice *)device didReceivePresenceUpdate:(TCPresenceEvent *)presenceEvent {
+ NSString *available = [NSString stringWithFormat:@"%d", presenceEvent.isAvailable];
+ NSDictionary *object = [NSDictionary dictionaryWithObjectsAndKeys:presenceEvent.name, @"from", available, @"available", nil];
+ [self javascriptCallback:@"onpresence" withArguments:object];
+}
+
+-(void)deviceDidStartListeningForIncomingConnections:(TCDevice *)device {
+ // What to do here? The JS library doesn't have an event for this.
+}
+
+# pragma mark connection delegate methods
+
+-(void)connection:(TCConnection*)connection didFailWithError:(NSError*)error {
+ [self javascriptErrorback:error];
+}
+
+-(void)connectionDidStartConnecting:(TCConnection*)connection {
+ self.connection = connection;
+ // What to do here? The JS library doesn't have an event for connection negotiation.
+}
+
+-(void)connectionDidConnect:(TCConnection*)connection {
+ self.connection = connection;
+ [self javascriptCallback:@"onconnect"];
+ if([connection isIncoming]) [self javascriptCallback:@"onaccept"];
+}
+
+-(void)connectionDidDisconnect:(TCConnection*)connection {
+ self.connection = connection;
+ [self javascriptCallback:@"ondevicedisconnect"];
+ [self javascriptCallback:@"onconnectiondisconnect"];
+}
+
+# pragma mark javascript device mapper methods
+
+-(void)deviceSetup:(CDVInvokedUrlCommand*)command {
+ self.callback = command.callbackId;
+ _nbRepeats = 0;
+
+ self.device = [[TCDevice alloc] initWithCapabilityToken:command.arguments[0] delegate:self];
+
+ // Disable sounds. was getting EXC_BAD_ACCESS
+ //self.device.incomingSoundEnabled = NO;
+ //self.device.outgoingSoundEnabled = NO;
+ //self.device.disconnectSoundEnabled = NO;
+
+ _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(deviceStatusEvent) userInfo:nil repeats:YES];
+}
+
+-(void)deviceStatusEvent {
+
+ NSLog(@"Device state: %ld",(long) self.device.state);
+
+ switch ([self.device state]) {
+
+ case TCDeviceStateReady:
+ [self javascriptCallback:@"onready"];
+ NSLog(@"State: Ready");
+
+ [_timer invalidate];
+ _timer = nil;
+
+ break;
+
+ case TCDeviceStateOffline:
+ [self javascriptCallback:@"onoffline"];
+ NSLog(@"State: Offline");
+
+ if ((long)_nbRepeats>20){
+
+ [_timer invalidate];
+ _timer = nil;
+ _nbRepeats = 0;
+ }
+ else _nbRepeats++;
+
+ break;
+
+ default:
+
+ [_timer invalidate];
+ _timer = nil;
+
+ break;
+ }
+}
+
+-(void)connect:(CDVInvokedUrlCommand*)command {
+ [self.device connect:[command.arguments objectAtIndex:0] delegate:self];
+}
+
+-(void)disconnectAll:(CDVInvokedUrlCommand*)command {
+ [self.device disconnectAll];
+}
+
+-(void)deviceStatus:(CDVInvokedUrlCommand*)command {
+ NSString *state;
+
+ NSLog(@"Device state: %ld",(long) self.device.state);
+
+ switch ([self.device state]) {
+ case TCDeviceStateBusy:
+ state = @"busy";
+ break;
+
+ case TCDeviceStateReady:
+ state = @"ready";
+ break;
+
+ case TCDeviceStateOffline:
+ state = @"offline";
+ break;
+
+ default:
+ break;
+ }
+
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:state];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+}
+
+
+# pragma mark javascript connection mapper methods
+
+-(void)acceptConnection:(CDVInvokedUrlCommand*)command {
+ [self.connection accept];
+}
+
+-(void)disconnectConnection:(CDVInvokedUrlCommand*)command {
+ [self.connection disconnect];
+}
+
+-(void)rejectConnection:(CDVInvokedUrlCommand*)command {
+ [self.connection reject];
+}
+
+-(void)muteConnection:(CDVInvokedUrlCommand*)command {
+ if(self.connection.isMuted) {
+ self.connection.muted = NO;
+ } else {
+ self.connection.muted = YES;
+ }
+}
+
+-(void)sendDigits:(CDVInvokedUrlCommand*)command {
+ [self.connection sendDigits:[command.arguments objectAtIndex:0]];
+}
+
+-(void)connectionStatus:(CDVInvokedUrlCommand*)command {
+ NSString *state;
+
+ switch ([self.connection state]) {
+ case TCConnectionStateConnected:
+ state = @"open";
+ break;
+
+ case TCConnectionStateConnecting:
+ state = @"connecting";
+ break;
+
+ case TCConnectionStatePending:
+ state = @"pending";
+ break;
+
+ case TCConnectionStateDisconnected:
+ state = @"closed";
+
+ default:
+ break;
+ }
+
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:state];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+}
+
+-(void)connectionParameters:(CDVInvokedUrlCommand*)command {
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self.connection parameters]];
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+}
+
+
+-(void)showNotification:(CDVInvokedUrlCommand*)command {
+ @try {
+ [[UIApplication sharedApplication] cancelAllLocalNotifications];
+ }
+ @catch(NSException *exception) {
+ NSLog(@"Couldn't Cancel Notification");
+ }
+
+ NSString *alertBody = [command.arguments objectAtIndex:0];
+
+ NSString *ringSound = @"incoming.wav";
+ if([command.arguments count] == 2) {
+ ringSound = [command.arguments objectAtIndex:1];
+ }
+
+ _ringNotification = [[UILocalNotification alloc] init];
+ _ringNotification.alertBody = alertBody;
+ _ringNotification.alertAction = @"Answer";
+ _ringNotification.soundName = ringSound;
+ _ringNotification.fireDate = [NSDate date];
+ [[UIApplication sharedApplication] scheduleLocalNotification:_ringNotification];
+
+}
+
+-(void)cancelNotification:(CDVInvokedUrlCommand*)command {
+ [[UIApplication sharedApplication] cancelLocalNotification:_ringNotification];
+}
+
+-(void)setSpeaker:(CDVInvokedUrlCommand*)command {
+ NSString *mode = [command.arguments objectAtIndex:0];
+ if([mode isEqual: @"on"]) {
+ UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
+ AudioSessionSetProperty (
+ kAudioSessionProperty_OverrideAudioRoute,
+ sizeof (audioRouteOverride),
+ &audioRouteOverride
+ );
+ }
+ else {
+ UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
+ AudioSessionSetProperty (
+ kAudioSessionProperty_OverrideAudioRoute,
+ sizeof (audioRouteOverride),
+ &audioRouteOverride
+ );
+ }
+}
+
+# pragma mark private methods
+
+-(void)javascriptCallback:(NSString *)event withArguments:(NSDictionary *)arguments {
+ NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:event, @"callback", arguments, @"arguments", nil];
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:options];
+ result.keepCallback = [NSNumber numberWithBool:YES];
+
+ [self.commandDelegate sendPluginResult:result callbackId:self.callback];
+}
+
+-(void)javascriptCallback:(NSString *)event {
+ [self javascriptCallback:event withArguments:nil];
+}
+
+-(void)javascriptErrorback:(NSError *)error {
+ NSDictionary *object = [NSDictionary dictionaryWithObjectsAndKeys:[error localizedDescription], @"message", nil];
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:object];
+ result.keepCallback = [NSNumber numberWithBool:YES];
+
+ [self.commandDelegate sendPluginResult:result callbackId:self.callback];
+}
+
+@end
diff --git a/iOS/tcPlugin.js b/www/tcPlugin.js
similarity index 69%
rename from iOS/tcPlugin.js
rename to www/tcPlugin.js
index d5be4b7..25551d0 100644
--- a/iOS/tcPlugin.js
+++ b/www/tcPlugin.js
@@ -10,6 +10,7 @@
}
}
+
TwilioPlugin.Device.prototype.setup = function(token) {
// Take a token and instantiate a new device object
var error = function(error) {
@@ -18,7 +19,7 @@
}
var success = function(callback) {
- var argument = callback['arguments'] || new Twilio.Connection();
+ var argument = callback['arguments'] || new TwilioPlugin.Connection();
if (delegate[callback['callback']]) delegate[callback['callback']](argument);
}
@@ -36,7 +37,7 @@
}
TwilioPlugin.Device.prototype.disconnectAll = function() {
- Cordova.exec('TCPlugin.disconnectAll');
+ Cordova.exec(null,null,"TCPlugin","disconnectAll",[]);
}
TwilioPlugin.Device.prototype.disconnect = function(fn) {
@@ -67,11 +68,10 @@
delegate['onpresence'] = fn;
}
- TwilioPlugin.Device.prototype.status = function() {
- var status = Cordova.exec("TCPlugin.deviceStatus");
+ TwilioPlugin.Device.prototype.status = function(fn) {
+ Cordova.exec(fn,null,"TCPlugin","deviceStatus",[]);
}
- // Noops until I figure out why the hell using sounds in Phonegap gives EXC_BAD_ACCESS
TwilioPlugin.Device.prototype.sounds = {
incoming: function(boolean) {},
outgoing: function(boolean) {},
@@ -82,19 +82,36 @@
if (typeof(argument) == 'function') {
delegate['onaccept'] = argument;
} else {
- Cordova.exec("TCPlugin.acceptConnection");
+ Cordova.exec(null,null,"TCPlugin","acceptConnection",[]);
}
}
+ TwilioPlugin.Connection.prototype.showNotification = function(alertBody, ringSound) {
+ var args = [alertBody, ringSound];
+ if(ringSound === "undefined") {
+ args = [alertBody];
+ }
+ Cordova.exec(null, null, "TCPlugin", "showNotification", args);
+ }
+
+ TwilioPlugin.Connection.prototype.cancelNotification = function() {
+ Cordova.exec(null, null, "TCPlugin", "cancelNotification", []);
+ }
+
+ TwilioPlugin.Connection.prototype.setSpeaker = function(mode) {
+ // "on" or "off"
+ Cordova.exec(null, null, "TCPlugin", "setSpeaker", [mode]);
+ }
+
TwilioPlugin.Connection.prototype.reject = function() {
- Cordova.exec("TCPlugin.rejectConnection");
+ Cordova.exec(null,null,"TCPlugin","rejectConnection",[]);
}
TwilioPlugin.Connection.prototype.disconnect = function(fn) {
if (typeof(argument) == 'function') {
delegate['onconnectiondisconnect'] = argument;
} else {
- Cordova.exec("TCPlugin.disconnectConnection");
+ Cordova.exec(null,null,"TCPlugin","disconnectConnection",[]);
}
}
@@ -103,25 +120,29 @@
}
TwilioPlugin.Connection.prototype.mute = function() {
- Cordova.exec("TCPlugin.muteConnection");
+ Cordova.exec(null,null,"TCPlugin","muteConnection",[]);
}
TwilioPlugin.Connection.prototype.unmute = function() {
- Cordova.exec("TCPlugin.muteConnection");
+ Cordova.exec(null,null,"TCPlugin","muteConnection",[]);
}
TwilioPlugin.Connection.prototype.sendDigits = function(string) {
- Cordova.exec("TCPlugin.sendDigits", string);
+ Cordova.exec(null,null,"TCPlugin","sendDigits", [string]);
}
TwilioPlugin.Connection.prototype.status = function(fn) {
Cordova.exec(fn, null, "TCPlugin", "connectionStatus", []);
}
+
+ TwilioPlugin.Connection.prototype.parameters = function(fn) {
+ Cordova.exec(fn, null, "TCPlugin", "connectionParameters", []);
+ }
TwilioPlugin.install = function() {
if (!window.Twilio) window.Twilio = {};
if (!window.Twilio.Device) window.Twilio.Device = new TwilioPlugin.Device();
- if (!window.Twilio.Connection) window.Twilio.Connection = TwilioPlugin.Connection;
+ if (!window.Twilio.Connection) window.Twilio.Connection = new TwilioPlugin.Connection();
}
TwilioPlugin.install();