Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Features section #212

Merged
merged 3 commits into from
Oct 22, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 97 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Get started with Voice on Android:

- [Quickstart](#quickstart) - Run the quickstart app
- [New Features](#new-features) - New features in 3.X
- [Migration Guide](#migration-guide) - Migrating from 2.X to 3.X
- [Emulator Support](#emulator-support) - Android emulator support
- [Reducing APK Size](#reducing-apk-size) - Use ABI splits to reduce APK size
Expand Down Expand Up @@ -174,19 +175,109 @@ Enter a PSTN number and press the call button to place a call.

<img height="500px" src="https://github.com/twilio/voice-quickstart-android/raw/master/images/quickstart/make_call_to_number.png">

## New Features

Voice Android 3.X has a number of new features listed below:

1. [WebRTC](#feature1)
2. [Custom Parameters](#feature2)
3. [Hold](#feature3)
4. [Ringing](#feature4)
5. [Stats](#feature5)

#### <a name="feature1"></a>WebRTC

The SDK is built using Chromium WebRTC for Android. This ensures that over time developers will get the best real-time media streaming capabilities available for Android. Additionally, upgrades to new versions of Chromium WebRTC will happen without changing the public API whenever possible.

#### <a name="feature2"></a>Custom Parameters

Custom Parameters is now supported in `CallInvite`. `CallInvite.getCustomParamaters()` returns a map of custom parameters sent from the caller side to callee.

```Java
// Pass custom parameters in TwiML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial answerOnBridge="false" callerId="client:alice">
<Client>
<Identity>bob</Identity>
<Parameter name="caller_first_name" value="alice" />
<Parameter name="caller_last_name" value="smith" />
</Client>
</Dial>
</Response>
```
`callInvite.getCustomParameters()` returns a map of key-value pair passed in the TwiML.

```
"caller_first_name" -> "alice"
"caller_last_name" -> "smith"
```

#### <a name="feature3"></a>Hold

Previously, there was no way to hold a call. Hold can now be called on the `Call` object as follows:

```Java
call.hold(boolean);
```

#### <a name="feature4"></a>Ringing

Ringing is now provided as a call state. A callback corresponding to this state transition is emitted once before the `Call.Listener.onConnected(...)` callback when the callee is being alerted of a Call. The behavior of this callback is determined by the `answerOnBridge` flag provided in the `Dial` verb of your TwiML application associated with this client. If the `answerOnBridge` flag is `false`, which is the default, the `Call.Listener.onConnected(...)` callback will be emitted immediately after `Call.Listener.onRinging(...)`. If the `answerOnBridge` flag is `true`, this will cause the call to emit the onConnected callback only after the call is answered. See [answerOnBridge](https://www.twilio.com/docs/voice/twiml/dial#answeronbridge) for more details on how to use it with the Dial TwiML verb. If the TwiML response contains a Say verb, then the call will emit the `Call.Listener.onConnected(...)` callback immediately after `Call.Listener.onRinging(...)` is raised, irrespective of the value of `answerOnBridge` being set to `true` or `false`.

These changes are added as follows:

```Java
public class Call {

public enum State {
CONNECTING,
RINGING, // State addition
CONNECTED,
DISCONNECTED
}

public interface Listener {
void onConnectFailure(@NonNull Call call, @NonNull CallException callException);
void onRinging(@NonNull Call call); // Callback addition
void onConnected(@NonNull Call call);
void onDisconnected(@NonNull Call call, @Nullable CallException callException);
}
}
```

#### <a name="feature5"></a>Stats

Statistics related to the media in the call can now be retrieved by calling `Call.getStats(StatsListener listener)`. The `StatsListener` returns a `StatsReport` that provides statistics about the local and remote audio in the call.

## Migration Guide

This section describes API changes and additions to ease migration from Voice Android 2.X to Voice Android 3.X. Each section provides code snippets to assist in transitioning to the new API.
This section describes API or behavioral changes when upgrading from Voice Android 2.X to Voice Android 3.X. Each section provides code snippets to assist in transitioning to the new API.

#### Call State
1. [Making a Call](#migration1)
2. [Call State](#migration2)
3. [CallInvite Changes](#migration3)
4. [Specifying a Media Region](#migration4)
5. [ConnectOptions & AcceptOptions](#migration5)
6. [Media Establishment & Connectivity](#migration6)

#### <a name="migration1"></a>Making a Call

In Voice 3.X, the API to make a call has changed from `Voice.call(...)` to `Voice.connect(...)`.

```Java
Call call = Voice.connect(context, accessToken, listener);
```

#### <a name="migration2"></a>Call State

The call state `CallState` has moved to the Call class. It can be referenced as follows:

```Java
Call.State
```

#### CallInvite Changes
#### <a name="migration3"></a>CallInvite Changes

In Voice Android 3.X, the `MessageListener` no longer raises errors if an invalid message is provided, instead a `boolean` value is returned when `boolean handleMessage(context, data, listener)` is called. The `boolean` value returns `true` when the provided data resulted in a `CallInvite` or `CancelledCallInvite` raised by the `MessageListener`. If `boolean handleMessage(context, data, listener)` returns `false` it means the data provided was not a Twilio Voice push message.

Expand All @@ -208,7 +299,7 @@ boolean valid = handleMessage(context, data, new MessageListener() {

The `CallInvite` has an `accept()` and `reject()` method. The `getState()` method has been removed from the `CallInvite` in favor of distinguishing between call invites and call invite cancellations with discrete stateless objects. While the `CancelledCallInvite` simply provides the `to`, `from`, and `callSid` fields also available in the `CallInvite`. The class method `getCallSid()` can be used to associate a `CallInvite` with a `CancelledCallInvite`.

#### Specifying a media region
#### <a name="migration4"></a>Specifying a media region

Previously, a media region could be specified via `Voice.setRegion(String)`. Now this configuration can be provided as part of `ConnectOptions` or `AcceptOptions` as shown below:

Expand All @@ -222,7 +313,7 @@ AcceptOptions acceptOptions = new AcceptOptions.Builder()
.build();
```

#### ConnectOptions & AcceptOptions
#### <a name="migration5"></a>ConnectOptions & AcceptOptions

To support configurability upon making or accepting a call new classes have been added. To create `ConnectOptions` the `ConnectOptions.Builder` must be used. Once `ConnectOptions` is created it can be provided when connecting a `Call` as shown below:

Expand All @@ -241,41 +332,7 @@ AcceptOptions acceptOptions = new AcceptOptions.Builder()
CallInvite.accept(context, acceptOptions, listener);
```

#### Ringing

Ringing is now provided as a call state. A callback corresponding to this state transition is emitted once before the `Call.Listener.onConnected(...)` callback when the callee is being alerted of a Call. The behavior of this callback is determined by the `answerOnBridge` flag provided in the `Dial` verb of your TwiML application associated with this client. If the `answerOnBridge` flag is `false`, which is the default, the `Call.Listener.onConnected(...)` callback will be emitted immediately after `Call.Listener.onRinging(...)`. If the `answerOnBridge` flag is `true`, this will cause the call to emit the onConnected callback only after the call is answered. See [answerOnBridge](https://www.twilio.com/docs/voice/twiml/dial#answeronbridge) for more details on how to use it with the Dial TwiML verb. If the TwiML response contains a Say verb, then the call will emit the `Call.Listener.onConnected(...)` callback immediately after `Call.Listener.onRinging(...)` is raised, irrespective of the value of `answerOnBridge` being set to `true` or `false`.

These changes are added as follows:

```Java
public class Call {

public enum State {
CONNECTING,
RINGING, // State addition
CONNECTED,
DISCONNECTED
}

public interface Listener {
void onConnectFailure(@NonNull Call call, @NonNull CallException callException);
void onRinging(@NonNull Call call); // Callback addition
void onConnected(@NonNull Call call);
void onDisconnected(@NonNull Call call, @Nullable CallException callException);
}
}

```

#### Hold

Previously, there was no way to hold a call. Hold can now be called on the `Call` object as follows:

```Java
call.hold(boolean);
```

#### Media Establishment & Connectivity
#### <a name="migration6"></a>Media Establishment & Connectivity

The Voice Android 3.X SDK uses WebRTC. The exchange of real-time media requires the use of Interactive Connectivity Establishment(ICE) to establish a media connection between the client and the media server. In some network environments where network access is restricted it may be necessary to provide ICE servers to establish a media connection. We reccomend using the [Network Traversal Service (NTS)](https://www.twilio.com/stun-turn) to obtain ICE servers. ICE servers can be provided when making or accepting a call by passing them into `ConnectOptions` or `AcceptOptions` in the following way:

Expand All @@ -295,30 +352,6 @@ ConnectOptions.Builder connectOptionsBuilder = new ConnectOptions.Builder(access
.build();
```

### Custom Parameters

Custom Parameters is now supported in `CallInvite`. `CallInvite.getCustomParamaters()` returns a map of custom parameters sent from the caller side to callee.

```Java
// Pass custom parameters in TwiML
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial answerOnBridge="false" callerId="client:alice">
<Client>
<Identity>bob</Identity>
<Parameter name="caller_first_name" value="alice" />
<Parameter name="caller_last_name" value="smith" />
</Client>
</Dial>
</Response>
```
`callInvite.getCustomParameters()` returns a map of key-value pair passed in the TwiML.

```
"caller_first_name" -> "alice"
"caller_last_name" -> "smith"
```

## Emulator Support

The SDK supports using emulators except in the following known cases:
Expand Down