1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.rtp; 18 19 import java.net.InetAddress; 20 import java.net.SocketException; 21 22 /** 23 * An AudioStream is a {@link RtpStream} which carrys audio payloads over 24 * Real-time Transport Protocol (RTP). Two different classes are developed in 25 * order to support various usages such as audio conferencing. An AudioStream 26 * represents a remote endpoint which consists of a network mapping and a 27 * configured {@link AudioCodec}. On the other side, An {@link AudioGroup} 28 * represents a local endpoint which mixes all the AudioStreams and optionally 29 * interacts with the speaker and the microphone at the same time. The simplest 30 * usage includes one for each endpoints. For other combinations, developers 31 * should be aware of the limitations described in {@link AudioGroup}. 32 * 33 * <p>An AudioStream becomes busy when it joins an AudioGroup. In this case most 34 * of the setter methods are disabled. This is designed to ease the task of 35 * managing native resources. One can always make an AudioStream leave its 36 * AudioGroup by calling {@link #join(AudioGroup)} with {@code null} and put it 37 * back after the modification is done.</p> 38 * 39 * <p class="note">Using this class requires 40 * {@link android.Manifest.permission#INTERNET} permission.</p> 41 * 42 * @see RtpStream 43 * @see AudioGroup 44 * @deprecated {@link android.net.sip.SipManager} and associated classes are no longer supported and 45 * should not be used as the basis of future VOIP apps. 46 */ 47 public class AudioStream extends RtpStream { 48 private AudioCodec mCodec; 49 private int mDtmfType = -1; 50 private AudioGroup mGroup; 51 52 /** 53 * Creates an AudioStream on the given local address. Note that the local 54 * port is assigned automatically to conform with RFC 3550. 55 * 56 * @param address The network address of the local host to bind to. 57 * @throws SocketException if the address cannot be bound or a problem 58 * occurs during binding. 59 */ AudioStream(InetAddress address)60 public AudioStream(InetAddress address) throws SocketException { 61 super(address); 62 } 63 64 /** 65 * Returns {@code true} if the stream has already joined an 66 * {@link AudioGroup}. 67 */ 68 @Override isBusy()69 public final boolean isBusy() { 70 return mGroup != null; 71 } 72 73 /** 74 * Returns the joined {@link AudioGroup}. 75 */ getGroup()76 public AudioGroup getGroup() { 77 return mGroup; 78 } 79 80 /** 81 * Joins an {@link AudioGroup}. Each stream can join only one group at a 82 * time. The group can be changed by passing a different one or removed 83 * by calling this method with {@code null}. 84 * 85 * @param group The AudioGroup to join or {@code null} to leave. 86 * @throws IllegalStateException if the stream is not properly configured. 87 * @see AudioGroup 88 */ join(AudioGroup group)89 public void join(AudioGroup group) { 90 synchronized (this) { 91 if (mGroup == group) { 92 return; 93 } 94 if (mGroup != null) { 95 mGroup.remove(this); 96 mGroup = null; 97 } 98 if (group != null) { 99 group.add(this); 100 mGroup = group; 101 } 102 } 103 } 104 105 /** 106 * Returns the {@link AudioCodec}, or {@code null} if it is not set. 107 * 108 * @see #setCodec(AudioCodec) 109 */ getCodec()110 public AudioCodec getCodec() { 111 return mCodec; 112 } 113 114 /** 115 * Sets the {@link AudioCodec}. 116 * 117 * @param codec The AudioCodec to be used. 118 * @throws IllegalArgumentException if its type is used by DTMF. 119 * @throws IllegalStateException if the stream is busy. 120 */ setCodec(AudioCodec codec)121 public void setCodec(AudioCodec codec) { 122 if (isBusy()) { 123 throw new IllegalStateException("Busy"); 124 } 125 if (codec.type == mDtmfType) { 126 throw new IllegalArgumentException("The type is used by DTMF"); 127 } 128 mCodec = codec; 129 } 130 131 /** 132 * Returns the RTP payload type for dual-tone multi-frequency (DTMF) digits, 133 * or {@code -1} if it is not enabled. 134 * 135 * @see #setDtmfType(int) 136 */ getDtmfType()137 public int getDtmfType() { 138 return mDtmfType; 139 } 140 141 /** 142 * Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits. 143 * The primary usage is to send digits to the remote gateway to perform 144 * certain tasks, such as second-stage dialing. According to RFC 2833, the 145 * RTP payload type for DTMF is assigned dynamically, so it must be in the 146 * range of 96 and 127. One can use {@code -1} to disable DTMF and free up 147 * the previous assigned type. This method cannot be called when the stream 148 * already joined an {@link AudioGroup}. 149 * 150 * @param type The RTP payload type to be used or {@code -1} to disable it. 151 * @throws IllegalArgumentException if the type is invalid or used by codec. 152 * @throws IllegalStateException if the stream is busy. 153 * @see AudioGroup#sendDtmf(int) 154 */ setDtmfType(int type)155 public void setDtmfType(int type) { 156 if (isBusy()) { 157 throw new IllegalStateException("Busy"); 158 } 159 if (type != -1) { 160 if (type < 96 || type > 127) { 161 throw new IllegalArgumentException("Invalid type"); 162 } 163 if (mCodec != null && type == mCodec.type) { 164 throw new IllegalArgumentException("The type is used by codec"); 165 } 166 } 167 mDtmfType = type; 168 } 169 } 170