Commit cbb2a2a2 authored by Wink Saville's avatar Wink Saville

Delete frameworks/base/voip use voip-common from frameworks/opt/net/voip

Change-Id: Ieaba759a0f69b45c4b8839cbed1fe757cdf190c5
parent 29e4aa7a
......@@ -219,10 +219,7 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
voip/java/android/net/sip/ISipSession.aidl \
voip/java/android/net/sip/ISipSessionListener.aidl \
voip/java/android/net/sip/ISipService.aidl
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
#
......@@ -353,6 +350,8 @@ non_base_dirs := \
../../external/apache-http/src/org/apache/http \
../opt/telephony/src/java/android/telephony \
../opt/telephony/src/java/android/telephony/gsm \
../opt/net/voip/src/java/android/net/rtp \
../opt/net/voip/src/java/android/net/sip
# These are relative to frameworks/base
dirs_to_check_apis := \
......@@ -405,6 +404,7 @@ framework_docs_LOCAL_JAVA_LIBRARIES := \
framework \
mms-common \
telephony-common \
voip-common \
framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
......
......@@ -149,6 +149,11 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationController.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationMediator.java)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/view/IDisplayMagnificationMediator.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/voip)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/librtp_jni_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/librtp_jni.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/librtp_jni.so)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/librtp_jni.so)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
......
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.rtp;
import java.util.Arrays;
/**
* This class defines a collection of audio codecs to be used with
* {@link AudioStream}s. Their parameters are designed to be exchanged using
* Session Description Protocol (SDP). Most of the values listed here can be
* found in RFC 3551, while others are described in separated standards.
*
* <p>Few simple configurations are defined as public static instances for the
* convenience of direct uses. More complicated ones could be obtained using
* {@link #getCodec(int, String, String)}. For example, one can use the
* following snippet to create a mode-1-only AMR codec.</p>
* <pre>
* AudioCodec codec = AudioCodec.getCodec(100, "AMR/8000", "mode-set=1");
* </pre>
*
* @see AudioStream
*/
public class AudioCodec {
/**
* The RTP payload type of the encoding.
*/
public final int type;
/**
* The encoding parameters to be used in the corresponding SDP attribute.
*/
public final String rtpmap;
/**
* The format parameters to be used in the corresponding SDP attribute.
*/
public final String fmtp;
/**
* G.711 u-law audio codec.
*/
public static final AudioCodec PCMU = new AudioCodec(0, "PCMU/8000", null);
/**
* G.711 a-law audio codec.
*/
public static final AudioCodec PCMA = new AudioCodec(8, "PCMA/8000", null);
/**
* GSM Full-Rate audio codec, also known as GSM-FR, GSM 06.10, GSM, or
* simply FR.
*/
public static final AudioCodec GSM = new AudioCodec(3, "GSM/8000", null);
/**
* GSM Enhanced Full-Rate audio codec, also known as GSM-EFR, GSM 06.60, or
* simply EFR.
*/
public static final AudioCodec GSM_EFR = new AudioCodec(96, "GSM-EFR/8000", null);
/**
* Adaptive Multi-Rate narrowband audio codec, also known as AMR or AMR-NB.
* Currently CRC, robust sorting, and interleaving are not supported. See
* more details about these features in RFC 4867.
*/
public static final AudioCodec AMR = new AudioCodec(97, "AMR/8000", null);
private static final AudioCodec[] sCodecs = {GSM_EFR, AMR, GSM, PCMU, PCMA};
private AudioCodec(int type, String rtpmap, String fmtp) {
this.type = type;
this.rtpmap = rtpmap;
this.fmtp = fmtp;
}
/**
* Returns system supported audio codecs.
*/
public static AudioCodec[] getCodecs() {
return Arrays.copyOf(sCodecs, sCodecs.length);
}
/**
* Creates an AudioCodec according to the given configuration.
*
* @param type The payload type of the encoding defined in RTP/AVP.
* @param rtpmap The encoding parameters specified in the corresponding SDP
* attribute, or null if it is not available.
* @param fmtp The format parameters specified in the corresponding SDP
* attribute, or null if it is not available.
* @return The configured AudioCodec or {@code null} if it is not supported.
*/
public static AudioCodec getCodec(int type, String rtpmap, String fmtp) {
if (type < 0 || type > 127) {
return null;
}
AudioCodec hint = null;
if (rtpmap != null) {
String clue = rtpmap.trim().toUpperCase();
for (AudioCodec codec : sCodecs) {
if (clue.startsWith(codec.rtpmap)) {
String channels = clue.substring(codec.rtpmap.length());
if (channels.length() == 0 || channels.equals("/1")) {
hint = codec;
}
break;
}
}
} else if (type < 96) {
for (AudioCodec codec : sCodecs) {
if (type == codec.type) {
hint = codec;
rtpmap = codec.rtpmap;
break;
}
}
}
if (hint == null) {
return null;
}
if (hint == AMR && fmtp != null) {
String clue = fmtp.toLowerCase();
if (clue.contains("crc=1") || clue.contains("robust-sorting=1") ||
clue.contains("interleaving=")) {
return null;
}
}
return new AudioCodec(type, rtpmap, fmtp);
}
}
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.rtp;
import android.media.AudioManager;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* An AudioGroup is an audio hub for the speaker, the microphone, and
* {@link AudioStream}s. Each of these components can be logically turned on
* or off by calling {@link #setMode(int)} or {@link RtpStream#setMode(int)}.
* The AudioGroup will go through these components and process them one by one
* within its execution loop. The loop consists of four steps. First, for each
* AudioStream not in {@link RtpStream#MODE_SEND_ONLY}, decodes its incoming
* packets and stores in its buffer. Then, if the microphone is enabled,
* processes the recorded audio and stores in its buffer. Third, if the speaker
* is enabled, mixes all AudioStream buffers and plays back. Finally, for each
* AudioStream not in {@link RtpStream#MODE_RECEIVE_ONLY}, mixes all other
* buffers and sends back the encoded packets. An AudioGroup does nothing if
* there is no AudioStream in it.
*
* <p>Few things must be noticed before using these classes. The performance is
* highly related to the system load and the network bandwidth. Usually a
* simpler {@link AudioCodec} costs fewer CPU cycles but requires more network
* bandwidth, and vise versa. Using two AudioStreams at the same time doubles
* not only the load but also the bandwidth. The condition varies from one
* device to another, and developers should choose the right combination in
* order to get the best result.</p>
*
* <p>It is sometimes useful to keep multiple AudioGroups at the same time. For
* example, a Voice over IP (VoIP) application might want to put a conference
* call on hold in order to make a new call but still allow people in the
* conference call talking to each other. This can be done easily using two
* AudioGroups, but there are some limitations. Since the speaker and the
* microphone are globally shared resources, only one AudioGroup at a time is
* allowed to run in a mode other than {@link #MODE_ON_HOLD}. The others will
* be unable to acquire these resources and fail silently.</p>
*
* <p class="note">Using this class requires
* {@link android.Manifest.permission#RECORD_AUDIO} permission. Developers
* should set the audio mode to {@link AudioManager#MODE_IN_COMMUNICATION}
* using {@link AudioManager#setMode(int)} and change it back when none of
* the AudioGroups is in use.</p>
*
* @see AudioStream
*/
public class AudioGroup {
/**
* This mode is similar to {@link #MODE_NORMAL} except the speaker and
* the microphone are both disabled.
*/
public static final int MODE_ON_HOLD = 0;
/**
* This mode is similar to {@link #MODE_NORMAL} except the microphone is
* disabled.
*/
public static final int MODE_MUTED = 1;
/**
* This mode indicates that the speaker, the microphone, and all
* {@link AudioStream}s in the group are enabled. First, the packets
* received from the streams are decoded and mixed with the audio recorded
* from the microphone. Then, the results are played back to the speaker,
* encoded and sent back to each stream.
*/
public static final int MODE_NORMAL = 2;
/**
* This mode is similar to {@link #MODE_NORMAL} except the echo suppression
* is enabled. It should be only used when the speaker phone is on.
*/
public static final int MODE_ECHO_SUPPRESSION = 3;
private static final int MODE_LAST = 3;
private final Map<AudioStream, Integer> mStreams;
private int mMode = MODE_ON_HOLD;
private int mNative;
static {
System.loadLibrary("rtp_jni");
}
/**
* Creates an empty AudioGroup.
*/
public AudioGroup() {
mStreams = new HashMap<AudioStream, Integer>();
}
/**
* Returns the {@link AudioStream}s in this group.
*/
public AudioStream[] getStreams() {
synchronized (this) {
return mStreams.keySet().toArray(new AudioStream[mStreams.size()]);
}
}
/**
* Returns the current mode.
*/
public int getMode() {
return mMode;
}
/**
* Changes the current mode. It must be one of {@link #MODE_ON_HOLD},
* {@link #MODE_MUTED}, {@link #MODE_NORMAL}, and
* {@link #MODE_ECHO_SUPPRESSION}.
*
* @param mode The mode to change to.
* @throws IllegalArgumentException if the mode is invalid.
*/
public void setMode(int mode) {
if (mode < 0 || mode > MODE_LAST) {
throw new IllegalArgumentException("Invalid mode");
}
synchronized (this) {
nativeSetMode(mode);
mMode = mode;
}
}
private native void nativeSetMode(int mode);
// Package-private method used by AudioStream.join().
synchronized void add(AudioStream stream) {
if (!mStreams.containsKey(stream)) {
try {
AudioCodec codec = stream.getCodec();
String codecSpec = String.format(Locale.US, "%d %s %s", codec.type,
codec.rtpmap, codec.fmtp);
int id = nativeAdd(stream.getMode(), stream.getSocket(),
stream.getRemoteAddress().getHostAddress(),
stream.getRemotePort(), codecSpec, stream.getDtmfType());
mStreams.put(stream, id);
} catch (NullPointerException e) {
throw new IllegalStateException(e);
}
}
}
private native int nativeAdd(int mode, int socket, String remoteAddress,
int remotePort, String codecSpec, int dtmfType);
// Package-private method used by AudioStream.join().
synchronized void remove(AudioStream stream) {
Integer id = mStreams.remove(stream);
if (id != null) {
nativeRemove(id);
}
}
private native void nativeRemove(int id);
/**
* Sends a DTMF digit to every {@link AudioStream} in this group. Currently
* only event {@code 0} to {@code 15} are supported.
*
* @throws IllegalArgumentException if the event is invalid.
*/
public void sendDtmf(int event) {
if (event < 0 || event > 15) {
throw new IllegalArgumentException("Invalid event");
}
synchronized (this) {
nativeSendDtmf(event);
}
}
private native void nativeSendDtmf(int event);
/**
* Removes every {@link AudioStream} in this group.
*/
public void clear() {
for (AudioStream stream : getStreams()) {
stream.join(null);
}
}
@Override
protected void finalize() throws Throwable {
nativeRemove(0);
super.finalize();
}
}
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.rtp;
import java.net.InetAddress;
import java.net.SocketException;
/**
* An AudioStream is a {@link RtpStream} which carrys audio payloads over
* Real-time Transport Protocol (RTP). Two different classes are developed in
* order to support various usages such as audio conferencing. An AudioStream
* represents a remote endpoint which consists of a network mapping and a
* configured {@link AudioCodec}. On the other side, An {@link AudioGroup}
* represents a local endpoint which mixes all the AudioStreams and optionally
* interacts with the speaker and the microphone at the same time. The simplest
* usage includes one for each endpoints. For other combinations, developers
* should be aware of the limitations described in {@link AudioGroup}.
*
* <p>An AudioStream becomes busy when it joins an AudioGroup. In this case most
* of the setter methods are disabled. This is designed to ease the task of
* managing native resources. One can always make an AudioStream leave its
* AudioGroup by calling {@link #join(AudioGroup)} with {@code null} and put it
* back after the modification is done.</p>
*
* <p class="note">Using this class requires
* {@link android.Manifest.permission#INTERNET} permission.</p>
*
* @see RtpStream
* @see AudioGroup
*/
public class AudioStream extends RtpStream {
private AudioCodec mCodec;
private int mDtmfType = -1;
private AudioGroup mGroup;
/**
* Creates an AudioStream on the given local address. Note that the local
* port is assigned automatically to conform with RFC 3550.
*
* @param address The network address of the local host to bind to.
* @throws SocketException if the address cannot be bound or a problem
* occurs during binding.
*/
public AudioStream(InetAddress address) throws SocketException {
super(address);
}
/**
* Returns {@code true} if the stream has already joined an
* {@link AudioGroup}.
*/
@Override
public final boolean isBusy() {
return mGroup != null;
}
/**
* Returns the joined {@link AudioGroup}.
*/
public AudioGroup getGroup() {
return mGroup;
}
/**
* Joins an {@link AudioGroup}. Each stream can join only one group at a
* time. The group can be changed by passing a different one or removed
* by calling this method with {@code null}.
*
* @param group The AudioGroup to join or {@code null} to leave.
* @throws IllegalStateException if the stream is not properly configured.
* @see AudioGroup
*/
public void join(AudioGroup group) {
synchronized (this) {
if (mGroup == group) {
return;
}
if (mGroup != null) {
mGroup.remove(this);
mGroup = null;
}
if (group != null) {
group.add(this);
mGroup = group;
}
}
}
/**
* Returns the {@link AudioCodec}, or {@code null} if it is not set.
*
* @see #setCodec(AudioCodec)
*/
public AudioCodec getCodec() {
return mCodec;
}
/**
* Sets the {@link AudioCodec}.
*
* @param codec The AudioCodec to be used.
* @throws IllegalArgumentException if its type is used by DTMF.
* @throws IllegalStateException if the stream is busy.
*/
public void setCodec(AudioCodec codec) {
if (isBusy()) {
throw new IllegalStateException("Busy");
}
if (codec.type == mDtmfType) {
throw new IllegalArgumentException("The type is used by DTMF");
}
mCodec = codec;
}
/**
* Returns the RTP payload type for dual-tone multi-frequency (DTMF) digits,
* or {@code -1} if it is not enabled.
*
* @see #setDtmfType(int)
*/
public int getDtmfType() {
return mDtmfType;
}
/**
* Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits.
* The primary usage is to send digits to the remote gateway to perform
* certain tasks, such as second-stage dialing. According to RFC 2833, the
* RTP payload type for DTMF is assigned dynamically, so it must be in the
* range of 96 and 127. One can use {@code -1} to disable DTMF and free up
* the previous assigned type. This method cannot be called when the stream
* already joined an {@link AudioGroup}.
*
* @param type The RTP payload type to be used or {@code -1} to disable it.
* @throws IllegalArgumentException if the type is invalid or used by codec.
* @throws IllegalStateException if the stream is busy.
* @see AudioGroup#sendDtmf(int)
*/
public void setDtmfType(int type) {
if (isBusy()) {
throw new IllegalStateException("Busy");
}
if (type != -1) {
if (type < 96 || type > 127) {
throw new IllegalArgumentException("Invalid type");
}
if (mCodec != null && type == mCodec.type) {
throw new IllegalArgumentException("The type is used by codec");
}
}
mDtmfType = type;
}
}
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.rtp;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.SocketException;
/**
* RtpStream represents the base class of streams which send and receive network
* packets with media payloads over Real-time Transport Protocol (RTP).
*
* <p class="note">Using this class requires
* {@link android.Manifest.permission#INTERNET} permission.</p>
*/
public class RtpStream {
/**
* This mode indicates that the stream sends and receives packets at the
* same time. This is the initial mode for new streams.
*/
public static final int MODE_NORMAL = 0;
/**
* This mode indicates that the stream only sends packets.
*/
public static final int MODE_SEND_ONLY = 1;
/**
* This mode indicates that the stream only receives packets.
*/
public static final int MODE_RECEIVE_ONLY = 2;
private static final int MODE_LAST = 2;
private final InetAddress mLocalAddress;
private final int mLocalPort;
private InetAddress mRemoteAddress;
private int mRemotePort = -1;
private int mMode = MODE_NORMAL;
private int mSocket = -1;
static {
System.loadLibrary("rtp_jni");
}
/**
* Creates a RtpStream on the given local address. Note that the local
* port is assigned automatically to conform with RFC 3550.
*
* @param address The network address of the local host to bind to.
* @throws SocketException if the address cannot be bound or a problem
* occurs during binding.
*/
RtpStream(InetAddress address) throws SocketException {
mLocalPort = create(address.getHostAddress());
mLocalAddress = address;
}
private native int create(String address) throws SocketException;
/**
* Returns the network address of the local host.
*/
public InetAddress getLocalAddress() {
return mLocalAddress;
}
/**
* Returns the network port of the local host.
*/
public int getLocalPort() {
return mLocalPort;
}
/**
* Returns the network address of the remote host or {@code null} if the
* stream is not associated.
*/
public InetAddress getRemoteAddress() {
return mRemoteAddress;
}
/**
* Returns the network port of the remote host or {@code -1} if the stream
* is not associated.
*/
public int getRemotePort() {
return mRemotePort;
}
/**
* Returns {@code true} if the stream is busy. In this case most of the
* setter methods are disabled. This method is intended to be overridden
* by subclasses.
*/
public boolean isBusy() {
return false;
}
/**
* Returns the current mode.
*/
public int getMode() {
return mMode;
}
/**
* Changes the current mode. It must be one of {@link #MODE_NORMAL},
* {@link #MODE_SEND_ONLY}, and {@link #MODE_RECEIVE_ONLY}.
*
* @param mode The mode to change to.
* @throws IllegalArgumentException if the mode is invalid.
* @throws IllegalStateException if the stream is busy.
* @see #isBusy()
*/
public void setMode(int mode) {
if (isBusy()) {
throw new IllegalStateException("Busy");
}
if (mode < 0 || mode > MODE_LAST) {
throw new IllegalArgumentException("Invalid mode");
}
mMode = mode;
}
/**
* Associates with a remote host. This defines the destination of the
* outgoing packets.
*
* @param address The network address of the remote host.
* @param port The network port of the remote host.
* @throws IllegalArgumentException if the address is not supported or the
* port is invalid.
* @throws IllegalStateException if the stream is busy.
* @see #isBusy()
*/
public void associate(InetAddress address, int port) {
if (isBusy()) {
throw new IllegalStateException("Busy");
}
if (!(address instanceof Inet4Address && mLocalAddress instanceof Inet4Address) &&
!(address instanceof Inet6Address && mLocalAddress instanceof Inet6Address)) {