Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52bdfb9c authored by Chia-chi Yeh's avatar Chia-chi Yeh Committed by Android (Google) Code Review
Browse files

Merge "RTP: refactor a little bit and fix few minor bugs."

parents a8cc6a2c e6695050
Loading
Loading
Loading
Loading
+13 −14
Original line number Diff line number Diff line
@@ -142,34 +142,34 @@ public class AudioGroup {
    private native void nativeSetMode(int mode);

    // Package-private method used by AudioStream.join().
    synchronized void add(AudioStream stream, AudioCodec codec, int dtmfType) {
    synchronized void add(AudioStream stream) {
        if (!mStreams.containsKey(stream)) {
            try {
                int socket = stream.dup();
                AudioCodec codec = stream.getCodec();
                String codecSpec = String.format("%d %s %s", codec.type,
                        codec.rtpmap, codec.fmtp);
                nativeAdd(stream.getMode(), socket,
                int id = nativeAdd(stream.getMode(), stream.getSocket(),
                        stream.getRemoteAddress().getHostAddress(),
                        stream.getRemotePort(), codecSpec, dtmfType);
                mStreams.put(stream, socket);
                        stream.getRemotePort(), codecSpec, stream.getDtmfType());
                mStreams.put(stream, id);
            } catch (NullPointerException e) {
                throw new IllegalStateException(e);
            }
        }
    }

    private native void nativeAdd(int mode, int socket, String remoteAddress,
    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 socket = mStreams.remove(stream);
        if (socket != null) {
            nativeRemove(socket);
        Integer id = mStreams.remove(stream);
        if (id != null) {
            nativeRemove(id);
        }
    }

    private native void nativeRemove(int socket);
    private native void nativeRemove(int id);

    /**
     * Sends a DTMF digit to every {@link AudioStream} in this group. Currently
@@ -192,15 +192,14 @@ public class AudioGroup {
     * Removes every {@link AudioStream} in this group.
     */
    public void clear() {
        synchronized (this) {
            mStreams.clear();
            nativeRemove(-1);
        for (AudioStream stream : getStreams()) {
            stream.join(null);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        clear();
        nativeRemove(0);
        super.finalize();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ public class AudioStream extends RtpStream {
                mGroup = null;
            }
            if (group != null) {
                group.add(this, mCodec, mDtmfType);
                group.add(this);
                mGroup = group;
            }
        }
+10 −6
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ public class RtpStream {
    private int mRemotePort = -1;
    private int mMode = MODE_NORMAL;

    private int mNative;
    private int mSocket = -1;
    static {
        System.loadLibrary("rtp_jni");
    }
@@ -165,7 +165,9 @@ public class RtpStream {
        mRemotePort = port;
    }

    synchronized native int dup();
    int getSocket() {
        return mSocket;
    }

    /**
     * Releases allocated resources. The stream becomes inoperable after calling
@@ -175,13 +177,15 @@ public class RtpStream {
     * @see #isBusy()
     */
    public void release() {
        synchronized (this) {
            if (isBusy()) {
                throw new IllegalStateException("Busy");
            }
            close();
        }
    }

    private synchronized native void close();
    private native void close();

    @Override
    protected void finalize() throws Throwable {
+23 −17
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ public:
    bool setMode(int mode);
    bool sendDtmf(int event);
    bool add(AudioStream *stream);
    bool remove(int socket);
    bool remove(AudioStream *stream);
    bool platformHasAec() { return mPlatformHasAec; }

private:
@@ -691,20 +691,19 @@ bool AudioGroup::add(AudioStream *stream)
    return true;
}

bool AudioGroup::remove(int socket)
bool AudioGroup::remove(AudioStream *stream)
{
    mNetworkThread->requestExitAndWait();

    for (AudioStream *stream = mChain; stream->mNext; stream = stream->mNext) {
        AudioStream *target = stream->mNext;
        if (target->mSocket == socket) {
            if (epoll_ctl(mEventQueue, EPOLL_CTL_DEL, socket, NULL)) {
    for (AudioStream *chain = mChain; chain->mNext; chain = chain->mNext) {
        if (chain->mNext == stream) {
            if (epoll_ctl(mEventQueue, EPOLL_CTL_DEL, stream->mSocket, NULL)) {
                ALOGE("epoll_ctl: %s", strerror(errno));
                return false;
            }
            stream->mNext = target->mNext;
            ALOGD("stream[%d] leaves group[%d]", socket, mDeviceSocket);
            delete target;
            chain->mNext = stream->mNext;
            ALOGD("stream[%d] leaves group[%d]", stream->mSocket, mDeviceSocket);
            delete stream;
            break;
        }
    }
@@ -931,7 +930,7 @@ exit:
static jfieldID gNative;
static jfieldID gMode;

void add(JNIEnv *env, jobject thiz, jint mode,
int add(JNIEnv *env, jobject thiz, jint mode,
    jint socket, jstring jRemoteAddress, jint remotePort,
    jstring jCodecSpec, jint dtmfType)
{
@@ -943,16 +942,22 @@ void add(JNIEnv *env, jobject thiz, jint mode,
    sockaddr_storage remote;
    if (parse(env, jRemoteAddress, remotePort, &remote) < 0) {
        // Exception already thrown.
        return;
        return 0;
    }
    if (!jCodecSpec) {
        jniThrowNullPointerException(env, "codecSpec");
        return;
        return 0;
    }
    const char *codecSpec = env->GetStringUTFChars(jCodecSpec, NULL);
    if (!codecSpec) {
        // Exception already thrown.
        return;
        return 0;
    }
    socket = dup(socket);
    if (socket == -1) {
        jniThrowException(env, "java/lang/IllegalStateException",
            "cannot get stream socket");
        return 0;
    }

    // Create audio codec.
@@ -1001,7 +1006,7 @@ void add(JNIEnv *env, jobject thiz, jint mode,

    // Succeed.
    env->SetIntField(thiz, gNative, (int)group);
    return;
    return (int)stream;

error:
    delete group;
@@ -1009,13 +1014,14 @@ error:
    delete codec;
    close(socket);
    env->SetIntField(thiz, gNative, 0);
    return 0;
}

void remove(JNIEnv *env, jobject thiz, jint socket)
void remove(JNIEnv *env, jobject thiz, jint stream)
{
    AudioGroup *group = (AudioGroup *)env->GetIntField(thiz, gNative);
    if (group) {
        if (socket == -1 || !group->remove(socket)) {
        if (!stream || !group->remove((AudioStream *)stream)) {
            delete group;
            env->SetIntField(thiz, gNative, 0);
        }
@@ -1039,7 +1045,7 @@ void sendDtmf(JNIEnv *env, jobject thiz, jint event)
}

JNINativeMethod gMethods[] = {
    {"nativeAdd", "(IILjava/lang/String;ILjava/lang/String;I)V", (void *)add},
    {"nativeAdd", "(IILjava/lang/String;ILjava/lang/String;I)I", (void *)add},
    {"nativeRemove", "(I)V", (void *)remove},
    {"nativeSetMode", "(I)V", (void *)setMode},
    {"nativeSendDtmf", "(I)V", (void *)sendDtmf},
+7 −17
Original line number Diff line number Diff line
@@ -33,11 +33,11 @@ extern int parse(JNIEnv *env, jstring jAddress, int port, sockaddr_storage *ss);

namespace {

jfieldID gNative;
jfieldID gSocket;

jint create(JNIEnv *env, jobject thiz, jstring jAddress)
{
    env->SetIntField(thiz, gNative, -1);
    env->SetIntField(thiz, gSocket, -1);

    sockaddr_storage ss;
    if (parse(env, jAddress, 0, &ss) < 0) {
@@ -58,7 +58,7 @@ jint create(JNIEnv *env, jobject thiz, jstring jAddress)
        &((sockaddr_in *)&ss)->sin_port : &((sockaddr_in6 *)&ss)->sin6_port;
    uint16_t port = ntohs(*p);
    if ((port & 1) == 0) {
        env->SetIntField(thiz, gNative, socket);
        env->SetIntField(thiz, gSocket, socket);
        return port;
    }
    ::close(socket);
@@ -75,7 +75,7 @@ jint create(JNIEnv *env, jobject thiz, jstring jAddress)
            *p = htons(port);

            if (bind(socket, (sockaddr *)&ss, sizeof(ss)) == 0) {
                env->SetIntField(thiz, gNative, socket);
                env->SetIntField(thiz, gSocket, socket);
                return port;
            }
        }
@@ -86,25 +86,15 @@ jint create(JNIEnv *env, jobject thiz, jstring jAddress)
    return -1;
}

jint dup(JNIEnv *env, jobject thiz)
{
    int socket = ::dup(env->GetIntField(thiz, gNative));
    if (socket == -1) {
        jniThrowException(env, "java/lang/IllegalStateException", strerror(errno));
    }
    return socket;
}

void close(JNIEnv *env, jobject thiz)
{
    int socket = env->GetIntField(thiz, gNative);
    int socket = env->GetIntField(thiz, gSocket);
    ::close(socket);
    env->SetIntField(thiz, gNative, -1);
    env->SetIntField(thiz, gSocket, -1);
}

JNINativeMethod gMethods[] = {
    {"create", "(Ljava/lang/String;)I", (void *)create},
    {"dup", "()I", (void *)dup},
    {"close", "()V", (void *)close},
};

@@ -114,7 +104,7 @@ int registerRtpStream(JNIEnv *env)
{
    jclass clazz;
    if ((clazz = env->FindClass("android/net/rtp/RtpStream")) == NULL ||
        (gNative = env->GetFieldID(clazz, "mNative", "I")) == NULL ||
        (gSocket = env->GetFieldID(clazz, "mSocket", "I")) == NULL ||
        env->RegisterNatives(clazz, gMethods, NELEM(gMethods)) < 0) {
        ALOGE("JNI registration failed");
        return -1;