/*
 * Copyright (C) 2006 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.
 */

#define LOG_TAG "LocalSocketImpl"

#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <cutils/sockets.h>
#include <netinet/tcp.h>

namespace android {

static jfieldID field_inboundFileDescriptors;
static jfieldID field_outboundFileDescriptors;
static jclass class_Credentials;
static jclass class_FileDescriptor;
static jmethodID method_CredentialsInit;

/* private native void connectLocal(FileDescriptor fd,
 * String name, int namespace) throws IOException
 */
static void
socket_connect_local(JNIEnv *env, jobject object,
                        jobject fileDescriptor, jstring name, jint namespaceId)
{
    int ret;
    const char *nameUtf8;
    int fd;

    nameUtf8 = env->GetStringUTFChars(name, NULL);

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    ret = socket_local_client_connect(
                fd,
                nameUtf8,
                namespaceId,
                SOCK_STREAM);

    env->ReleaseStringUTFChars(name, nameUtf8);

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return;
    }
}

#define DEFAULT_BACKLOG 4

/* private native void bindLocal(FileDescriptor fd, String name, namespace)
 * throws IOException;
 */

static void
socket_bind_local (JNIEnv *env, jobject object, jobject fileDescriptor,
                jstring name, jint namespaceId)
{
    int ret;
    int fd;
    const char *nameUtf8;


    if (name == NULL) {
        jniThrowNullPointerException(env, NULL);
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    nameUtf8 = env->GetStringUTFChars(name, NULL);

    ret = socket_local_server_bind(fd, nameUtf8, namespaceId);

    env->ReleaseStringUTFChars(name, nameUtf8);

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return;
    }
}

/* private native void listen_native(int fd, int backlog) throws IOException; */
static void
socket_listen (JNIEnv *env, jobject object, jobject fileDescriptor, int backlog)
{
    int ret;
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    ret = listen(fd, backlog);

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return;
    }
}

/*    private native FileDescriptor
**    accept (FileDescriptor fd, LocalSocketImpl s)
**                                   throws IOException;
*/
static jobject
socket_accept (JNIEnv *env, jobject object, jobject fileDescriptor, jobject s)
{
    union {
        struct sockaddr address;
        struct sockaddr_un un_address;
    } sa;

    int ret;
    int retFD;
    int fd;
    socklen_t addrlen;

    if (s == NULL) {
        jniThrowNullPointerException(env, NULL);
        return NULL;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return NULL;
    }

    do {
        addrlen = sizeof(sa);
        ret = accept(fd, &(sa.address), &addrlen);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return NULL;
    }

    retFD = ret;

    return jniCreateFileDescriptor(env, retFD);
}

/* private native void shutdown(FileDescriptor fd, boolean shutdownInput) */

static void
socket_shutdown (JNIEnv *env, jobject object, jobject fileDescriptor,
                    jboolean shutdownInput)
{
    int ret;
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    ret = shutdown(fd, shutdownInput ? SHUT_RD : SHUT_WR);

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return;
    }
}

static bool
java_opt_to_real(int optID, int* opt, int* level)
{
    switch (optID)
    {
        case 4098:
            *opt = SO_RCVBUF;
            *level = SOL_SOCKET;
            return true;
        case 4097:
            *opt = SO_SNDBUF;
            *level = SOL_SOCKET;
            return true;
        case 4102:
            *opt = SO_SNDTIMEO;
            *level = SOL_SOCKET;
            return true;
        case 128:
            *opt = SO_LINGER;
            *level = SOL_SOCKET;
            return true;
        case 1:
            *opt = TCP_NODELAY;
            *level = IPPROTO_TCP;
            return true;
        case 4:
            *opt = SO_REUSEADDR;
            *level = SOL_SOCKET;
            return true;

    }
    return false;
}

static jint
socket_getOption(JNIEnv *env, jobject object, jobject fileDescriptor, int optID)
{
    int ret, value;
    int opt, level;
    int fd;

    socklen_t size = sizeof(int);

    if (!java_opt_to_real(optID, &opt, &level)) {
        jniThrowIOException(env, -1);
        return 0;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return 0;
    }

    switch (opt)
    {
        case SO_LINGER:
        {
            struct linger lingr;
            size = sizeof(lingr);
            ret = getsockopt(fd, level, opt, &lingr, &size);
            if (!lingr.l_onoff) {
                value = -1;
            } else {
                value = lingr.l_linger;
            }
            break;
        }
        default:
            ret = getsockopt(fd, level, opt, &value, &size);
            break;
    }


    if (ret != 0) {
        jniThrowIOException(env, errno);
        return 0;
    }

    return value;
}

static void socket_setOption(
        JNIEnv *env, jobject object, jobject fileDescriptor, int optID,
        jint boolValue, jint intValue) {
    int ret;
    int optname;
    int level;
    int fd;

    if (!java_opt_to_real(optID, &optname, &level)) {
        jniThrowIOException(env, -1);
        return;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    switch (optname) {
        case SO_LINGER: {
            /*
             * SO_LINGER is special because it needs to use a special
             * "linger" struct as well as use the incoming boolean
             * argument specially.
             */
            struct linger lingr;
            lingr.l_onoff = boolValue ? 1 : 0; // Force it to be 0 or 1.
            lingr.l_linger = intValue;
            ret = setsockopt(fd, level, optname, &lingr, sizeof(lingr));
            break;
        }
        case SO_SNDTIMEO: {
            /*
             * SO_TIMEOUT from the core library gets converted to
             * SO_SNDTIMEO, but the option is supposed to set both
             * send and receive timeouts. Note: The incoming timeout
             * value is in milliseconds.
             */
            struct timeval timeout;
            timeout.tv_sec = intValue / 1000;
            timeout.tv_usec = (intValue % 1000) * 1000;

            ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
                    (void *)&timeout, sizeof(timeout));

            if (ret == 0) {
                ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,
                        (void *)&timeout, sizeof(timeout));
            }

            break;
        }
        default: {
            /*
             * In all other cases, the translated option level and
             * optname may be used directly for a call to setsockopt().
             */
            ret = setsockopt(fd, level, optname, &intValue, sizeof(intValue));
            break;
        }
    }

    if (ret != 0) {
        jniThrowIOException(env, errno);
        return;
    }
}
static jint socket_pending (JNIEnv *env, jobject object,
        jobject fileDescriptor)
{
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return (jint)-1;
    }

    int pending;
    int ret = ioctl(fd, TIOCOUTQ, &pending);

    // If this were a non-socket fd, there would be other cases to worry
    // about...

    //ALOGD("socket_pending, ioctl ret:%d, pending:%d", ret, pending);
    if (ret < 0) {
        jniThrowIOException(env, errno);
        return (jint) 0;
    }

    return (jint)pending;
}
static jint socket_available (JNIEnv *env, jobject object,
        jobject fileDescriptor)
{
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return (jint)-1;
    }

#if 1
    int avail;
    int ret = ioctl(fd, FIONREAD, &avail);

    // If this were a non-socket fd, there would be other cases to worry
    // about...

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return (jint) 0;
    }

    return (jint)avail;
#else
// there appears to be a bionic bug that prevents this version from working.

    ssize_t ret;
    struct msghdr msg;

    memset(&msg, 0, sizeof(msg));

    do {
        ret = recvmsg(fd, &msg, MSG_PEEK | MSG_DONTWAIT | MSG_NOSIGNAL);
    } while (ret < 0 && errno == EINTR);


    // MSG_PEEK returns 0 on EOF and EWOULDBLOCK on none available
    if (ret < 0 && errno == EWOULDBLOCK) {
        return 0;
    } if (ret < 0) {
        jniThrowIOException(env, errno);
        return -1;
    }

    return (jint)ret;
#endif
}

/**
 * Processes ancillary data, handling only
 * SCM_RIGHTS. Creates appropriate objects and sets appropriate
 * fields in the LocalSocketImpl object. Returns 0 on success
 * or -1 if an exception was thrown.
 */
static int socket_process_cmsg(JNIEnv *env, jobject thisJ, struct msghdr * pMsg)
{
    struct cmsghdr *cmsgptr;

    for (cmsgptr = CMSG_FIRSTHDR(pMsg);
            cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(pMsg, cmsgptr)) {

        if (cmsgptr->cmsg_level != SOL_SOCKET) {
            continue;
        }

        if (cmsgptr->cmsg_type == SCM_RIGHTS) {
            int *pDescriptors = (int *)CMSG_DATA(cmsgptr);
            jobjectArray fdArray;
            int count
                = ((cmsgptr->cmsg_len - CMSG_LEN(0)) / sizeof(int));

            if (count < 0) {
                jniThrowException(env, "java/io/IOException",
                    "invalid cmsg length");
            }

            fdArray = env->NewObjectArray(count, class_FileDescriptor, NULL);

            if (fdArray == NULL) {
                return -1;
            }

            for (int i = 0; i < count; i++) {
                jobject fdObject
                        = jniCreateFileDescriptor(env, pDescriptors[i]);

                if (env->ExceptionOccurred() != NULL) {
                    return -1;
                }

                env->SetObjectArrayElement(fdArray, i, fdObject);

                if (env->ExceptionOccurred() != NULL) {
                    return -1;
                }
            }

            env->SetObjectField(thisJ, field_inboundFileDescriptors, fdArray);

            if (env->ExceptionOccurred() != NULL) {
                return -1;
            }
        }
    }

    return 0;
}

/**
 * Reads data from a socket into buf, processing any ancillary data
 * and adding it to thisJ.
 *
 * Returns the length of normal data read, or -1 if an exception has
 * been thrown in this function.
 */
static ssize_t socket_read_all(JNIEnv *env, jobject thisJ, int fd,
        void *buffer, size_t len)
{
    ssize_t ret;
    ssize_t bytesread = 0;
    struct msghdr msg;
    struct iovec iv;
    unsigned char *buf = (unsigned char *)buffer;
    // Enough buffer for a pile of fd's. We throw an exception if
    // this buffer is too small.
    struct cmsghdr cmsgbuf[2*sizeof(cmsghdr) + 0x100];

    memset(&msg, 0, sizeof(msg));
    memset(&iv, 0, sizeof(iv));

    iv.iov_base = buf;
    iv.iov_len = len;

    msg.msg_iov = &iv;
    msg.msg_iovlen = 1;
    msg.msg_control = cmsgbuf;
    msg.msg_controllen = sizeof(cmsgbuf);

    do {
        ret = recvmsg(fd, &msg, MSG_NOSIGNAL);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0 && errno == EPIPE) {
        // Treat this as an end of stream
        return 0;
    }

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return -1;
    }

    if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) {
        // To us, any of the above flags are a fatal error

        jniThrowException(env, "java/io/IOException",
                "Unexpected error or truncation during recvmsg()");

        return -1;
    }

    if (ret >= 0) {
        socket_process_cmsg(env, thisJ, &msg);
    }

    return ret;
}

/**
 * Writes all the data in the specified buffer to the specified socket.
 *
 * Returns 0 on success or -1 if an exception was thrown.
 */
static int socket_write_all(JNIEnv *env, jobject object, int fd,
        void *buf, size_t len)
{
    ssize_t ret;
    struct msghdr msg;
    unsigned char *buffer = (unsigned char *)buf;
    memset(&msg, 0, sizeof(msg));

    jobjectArray outboundFds
            = (jobjectArray)env->GetObjectField(
                object, field_outboundFileDescriptors);

    if (env->ExceptionOccurred() != NULL) {
        return -1;
    }

    struct cmsghdr *cmsg;
    int countFds = outboundFds == NULL ? 0 : env->GetArrayLength(outboundFds);
    int fds[countFds];
    char msgbuf[CMSG_SPACE(countFds)];

    // Add any pending outbound file descriptors to the message
    if (outboundFds != NULL) {

        if (env->ExceptionOccurred() != NULL) {
            return -1;
        }

        for (int i = 0; i < countFds; i++) {
            jobject fdObject = env->GetObjectArrayElement(outboundFds, i);
            if (env->ExceptionOccurred() != NULL) {
                return -1;
            }

            fds[i] = jniGetFDFromFileDescriptor(env, fdObject);
            if (env->ExceptionOccurred() != NULL) {
                return -1;
            }
        }

        // See "man cmsg" really
        msg.msg_control = msgbuf;
        msg.msg_controllen = sizeof msgbuf;
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg->cmsg_len = CMSG_LEN(sizeof fds);
        memcpy(CMSG_DATA(cmsg), fds, sizeof fds);
    }

    // We only write our msg_control during the first write
    while (len > 0) {
        struct iovec iv;
        memset(&iv, 0, sizeof(iv));

        iv.iov_base = buffer;
        iv.iov_len = len;

        msg.msg_iov = &iv;
        msg.msg_iovlen = 1;

        do {
            ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
        } while (ret < 0 && errno == EINTR);

        if (ret < 0) {
            jniThrowIOException(env, errno);
            return -1;
        }

        buffer += ret;
        len -= ret;

        // Wipes out any msg_control too
        memset(&msg, 0, sizeof(msg));
    }

    return 0;
}

static jint socket_read (JNIEnv *env, jobject object, jobject fileDescriptor)
{
    int fd;
    int err;

    if (fileDescriptor == NULL) {
        jniThrowNullPointerException(env, NULL);
        return (jint)-1;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return (jint)0;
    }

    unsigned char buf;

    err = socket_read_all(env, object, fd, &buf, 1);

    if (err < 0) {
        jniThrowIOException(env, errno);
        return (jint)0;
    }

    if (err == 0) {
        // end of file
        return (jint)-1;
    }

    return (jint)buf;
}

static jint socket_readba (JNIEnv *env, jobject object,
        jbyteArray buffer, jint off, jint len, jobject fileDescriptor)
{
    int fd;
    jbyte* byteBuffer;
    int ret;

    if (fileDescriptor == NULL || buffer == NULL) {
        jniThrowNullPointerException(env, NULL);
        return (jint)-1;
    }

    if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) {
        jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
        return (jint)-1;
    }

    if (len == 0) {
        // because socket_read_all returns 0 on EOF
        return 0;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return (jint)-1;
    }

    byteBuffer = env->GetByteArrayElements(buffer, NULL);

    if (NULL == byteBuffer) {
        // an exception will have been thrown
        return (jint)-1;
    }

    ret = socket_read_all(env, object,
            fd, byteBuffer + off, len);

    // A return of -1 above means an exception is pending

    env->ReleaseByteArrayElements(buffer, byteBuffer, 0);

    return (jint) ((ret == 0) ? -1 : ret);
}

static void socket_write (JNIEnv *env, jobject object,
        jint b, jobject fileDescriptor)
{
    int fd;
    int err;

    if (fileDescriptor == NULL) {
        jniThrowNullPointerException(env, NULL);
        return;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    err = socket_write_all(env, object, fd, &b, 1);

    // A return of -1 above means an exception is pending
}

static void socket_writeba (JNIEnv *env, jobject object,
        jbyteArray buffer, jint off, jint len, jobject fileDescriptor)
{
    int fd;
    int err;
    jbyte* byteBuffer;

    if (fileDescriptor == NULL || buffer == NULL) {
        jniThrowNullPointerException(env, NULL);
        return;
    }

    if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) {
        jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
        return;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }

    byteBuffer = env->GetByteArrayElements(buffer,NULL);

    if (NULL == byteBuffer) {
        // an exception will have been thrown
        return;
    }

    err = socket_write_all(env, object, fd,
            byteBuffer + off, len);

    // A return of -1 above means an exception is pending

    env->ReleaseByteArrayElements(buffer, byteBuffer, JNI_ABORT);
}

static jobject socket_get_peer_credentials(JNIEnv *env,
        jobject object, jobject fileDescriptor)
{
    int err;
    int fd;

    if (fileDescriptor == NULL) {
        jniThrowNullPointerException(env, NULL);
        return NULL;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return NULL;
    }

    struct ucred creds;

    memset(&creds, 0, sizeof(creds));
    socklen_t szCreds = sizeof(creds);

    err = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);

    if (err < 0) {
        jniThrowIOException(env, errno);
        return NULL;
    }

    if (szCreds == 0) {
        return NULL;
    }

    return env->NewObject(class_Credentials, method_CredentialsInit,
            creds.pid, creds.uid, creds.gid);
}

#if 0
//TODO change this to return an instance of LocalSocketAddress
static jobject socket_getSockName(JNIEnv *env,
        jobject object, jobject fileDescriptor)
{
    int err;
    int fd;

    if (fileDescriptor == NULL) {
        jniThrowNullPointerException(env, NULL);
        return NULL;
    }

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

    if (env->ExceptionOccurred() != NULL) {
        return NULL;
    }

    union {
        struct sockaddr address;
        struct sockaddr_un un_address;
    } sa;

    memset(&sa, 0, sizeof(sa));

    socklen_t namelen = sizeof(sa);
    err = getsockname(fd, &(sa.address), &namelen);

    if (err < 0) {
        jniThrowIOException(env, errno);
        return NULL;
    }

    if (sa.address.sa_family != AF_UNIX) {
        // We think we're an impl only for AF_UNIX, so this should never happen.

        jniThrowIOException(env, EINVAL);
        return NULL;
    }

    if (sa.un_address.sun_path[0] == '\0') {
    } else {
    }




}
#endif

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
    {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption},
    {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption},
    {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
                                                (void*)socket_connect_local},
    {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local},
    {"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen},
    {"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
    {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
    {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
    {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
    {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
    {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
    {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
    {"write_native", "(ILjava/io/FileDescriptor;)V", (void*) socket_write},
    {"getPeerCredentials_native",
            "(Ljava/io/FileDescriptor;)Landroid/net/Credentials;",
            (void*) socket_get_peer_credentials}
    //,{"getSockName_native", "(Ljava/io/FileDescriptor;)Ljava/lang/String;",
    //        (void *) socket_getSockName}

};

int register_android_net_LocalSocketImpl(JNIEnv *env)
{
    jclass clazz;

    clazz = env->FindClass("android/net/LocalSocketImpl");

    if (clazz == NULL) {
        goto error;
    }

    field_inboundFileDescriptors = env->GetFieldID(clazz,
            "inboundFileDescriptors", "[Ljava/io/FileDescriptor;");

    if (field_inboundFileDescriptors == NULL) {
        goto error;
    }

    field_outboundFileDescriptors = env->GetFieldID(clazz,
            "outboundFileDescriptors", "[Ljava/io/FileDescriptor;");

    if (field_outboundFileDescriptors == NULL) {
        goto error;
    }

    class_Credentials = env->FindClass("android/net/Credentials");

    if (class_Credentials == NULL) {
        goto error;
    }

    class_Credentials = (jclass)env->NewGlobalRef(class_Credentials);

    class_FileDescriptor = env->FindClass("java/io/FileDescriptor");

    if (class_FileDescriptor == NULL) {
        goto error;
    }

    class_FileDescriptor = (jclass)env->NewGlobalRef(class_FileDescriptor);

    method_CredentialsInit
            = env->GetMethodID(class_Credentials, "<init>", "(III)V");

    if (method_CredentialsInit == NULL) {
        goto error;
    }

    return jniRegisterNativeMethods(env,
        "android/net/LocalSocketImpl", gMethods, NELEM(gMethods));

error:
    ALOGE("Error registering android.net.LocalSocketImpl");
    return -1;
}

};
