blob: a1f2377041e894e7c422e0e9ad7081312201df5c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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#define LOG_TAG "LocalSocketImpl"
18
Steven Moreland2279b252017-07-19 09:50:45 -070019#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020#include "jni.h"
21#include "utils/Log.h"
22#include "utils/misc.h"
23
24#include <stdio.h>
25#include <string.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <sys/un.h>
29#include <arpa/inet.h>
30#include <netinet/in.h>
31#include <stdlib.h>
32#include <errno.h>
33#include <unistd.h>
34#include <sys/ioctl.h>
35
36#include <cutils/sockets.h>
37#include <netinet/tcp.h>
Steven Moreland2279b252017-07-19 09:50:45 -070038#include <nativehelper/ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
40namespace android {
41
Andreas Gampe0f0b4912014-11-12 08:03:48 -080042template <typename T>
43void UNUSED(T t) {}
44
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045static jfieldID field_inboundFileDescriptors;
46static jfieldID field_outboundFileDescriptors;
47static jclass class_Credentials;
48static jclass class_FileDescriptor;
49static jmethodID method_CredentialsInit;
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051/* private native void connectLocal(FileDescriptor fd,
52 * String name, int namespace) throws IOException
53 */
54static void
55socket_connect_local(JNIEnv *env, jobject object,
56 jobject fileDescriptor, jstring name, jint namespaceId)
57{
58 int ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 int fd;
60
Torne (Richard Coles)771b1872017-03-16 15:52:46 +000061 if (name == NULL) {
62 jniThrowNullPointerException(env, NULL);
63 return;
64 }
65
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
67
Mathieu Chartier98671c32014-08-20 10:04:08 -070068 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 return;
70 }
71
You Kim092eb8d2012-12-04 00:46:17 +090072 ScopedUtfChars nameUtf8(env, name);
73
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 ret = socket_local_client_connect(
75 fd,
You Kim092eb8d2012-12-04 00:46:17 +090076 nameUtf8.c_str(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 namespaceId,
78 SOCK_STREAM);
79
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 if (ret < 0) {
81 jniThrowIOException(env, errno);
82 return;
83 }
84}
85
86#define DEFAULT_BACKLOG 4
87
Elliott Hughes69a017b2011-04-08 14:10:28 -070088/* private native void bindLocal(FileDescriptor fd, String name, namespace)
89 * throws IOException;
90 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091
92static void
93socket_bind_local (JNIEnv *env, jobject object, jobject fileDescriptor,
94 jstring name, jint namespaceId)
95{
96 int ret;
97 int fd;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
99 if (name == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700100 jniThrowNullPointerException(env, NULL);
You Kim092eb8d2012-12-04 00:46:17 +0900101 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 }
103
104 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
105
Mathieu Chartier98671c32014-08-20 10:04:08 -0700106 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 return;
108 }
109
You Kim092eb8d2012-12-04 00:46:17 +0900110 ScopedUtfChars nameUtf8(env, name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
You Kim092eb8d2012-12-04 00:46:17 +0900112 ret = socket_local_server_bind(fd, nameUtf8.c_str(), namespaceId);
Elliott Hughes69a017b2011-04-08 14:10:28 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 if (ret < 0) {
115 jniThrowIOException(env, errno);
116 return;
117 }
118}
119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120/**
Elliott Hughes69a017b2011-04-08 14:10:28 -0700121 * Processes ancillary data, handling only
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 * SCM_RIGHTS. Creates appropriate objects and sets appropriate
123 * fields in the LocalSocketImpl object. Returns 0 on success
124 * or -1 if an exception was thrown.
125 */
126static int socket_process_cmsg(JNIEnv *env, jobject thisJ, struct msghdr * pMsg)
127{
128 struct cmsghdr *cmsgptr;
129
Elliott Hughes69a017b2011-04-08 14:10:28 -0700130 for (cmsgptr = CMSG_FIRSTHDR(pMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(pMsg, cmsgptr)) {
132
133 if (cmsgptr->cmsg_level != SOL_SOCKET) {
134 continue;
135 }
136
137 if (cmsgptr->cmsg_type == SCM_RIGHTS) {
138 int *pDescriptors = (int *)CMSG_DATA(cmsgptr);
139 jobjectArray fdArray;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700140 int count
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 = ((cmsgptr->cmsg_len - CMSG_LEN(0)) / sizeof(int));
142
143 if (count < 0) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700144 jniThrowException(env, "java/io/IOException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 "invalid cmsg length");
You Kim092eb8d2012-12-04 00:46:17 +0900146 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 }
148
149 fdArray = env->NewObjectArray(count, class_FileDescriptor, NULL);
150
151 if (fdArray == NULL) {
152 return -1;
153 }
154
155 for (int i = 0; i < count; i++) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700156 jobject fdObject
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 = jniCreateFileDescriptor(env, pDescriptors[i]);
158
Mathieu Chartier98671c32014-08-20 10:04:08 -0700159 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 return -1;
161 }
162
163 env->SetObjectArrayElement(fdArray, i, fdObject);
164
Mathieu Chartier98671c32014-08-20 10:04:08 -0700165 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 return -1;
167 }
168 }
169
170 env->SetObjectField(thisJ, field_inboundFileDescriptors, fdArray);
171
Mathieu Chartier98671c32014-08-20 10:04:08 -0700172 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 return -1;
174 }
175 }
176 }
177
178 return 0;
179}
180
181/**
182 * Reads data from a socket into buf, processing any ancillary data
183 * and adding it to thisJ.
184 *
185 * Returns the length of normal data read, or -1 if an exception has
186 * been thrown in this function.
187 */
Elliott Hughes69a017b2011-04-08 14:10:28 -0700188static ssize_t socket_read_all(JNIEnv *env, jobject thisJ, int fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 void *buffer, size_t len)
190{
191 ssize_t ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 struct msghdr msg;
193 struct iovec iv;
194 unsigned char *buf = (unsigned char *)buffer;
195 // Enough buffer for a pile of fd's. We throw an exception if
196 // this buffer is too small.
197 struct cmsghdr cmsgbuf[2*sizeof(cmsghdr) + 0x100];
198
199 memset(&msg, 0, sizeof(msg));
200 memset(&iv, 0, sizeof(iv));
201
202 iv.iov_base = buf;
203 iv.iov_len = len;
204
205 msg.msg_iov = &iv;
206 msg.msg_iovlen = 1;
207 msg.msg_control = cmsgbuf;
208 msg.msg_controllen = sizeof(cmsgbuf);
209
Nick Kralevichb0e50792016-12-20 07:13:25 -0800210 ret = TEMP_FAILURE_RETRY(recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
212 if (ret < 0 && errno == EPIPE) {
213 // Treat this as an end of stream
214 return 0;
215 }
216
217 if (ret < 0) {
218 jniThrowIOException(env, errno);
219 return -1;
220 }
221
222 if ((msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) {
223 // To us, any of the above flags are a fatal error
224
Elliott Hughes69a017b2011-04-08 14:10:28 -0700225 jniThrowException(env, "java/io/IOException",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 "Unexpected error or truncation during recvmsg()");
227
228 return -1;
229 }
230
231 if (ret >= 0) {
232 socket_process_cmsg(env, thisJ, &msg);
233 }
234
235 return ret;
236}
237
238/**
239 * Writes all the data in the specified buffer to the specified socket.
240 *
241 * Returns 0 on success or -1 if an exception was thrown.
242 */
243static int socket_write_all(JNIEnv *env, jobject object, int fd,
244 void *buf, size_t len)
245{
246 ssize_t ret;
247 struct msghdr msg;
248 unsigned char *buffer = (unsigned char *)buf;
249 memset(&msg, 0, sizeof(msg));
250
Elliott Hughes69a017b2011-04-08 14:10:28 -0700251 jobjectArray outboundFds
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 = (jobjectArray)env->GetObjectField(
253 object, field_outboundFileDescriptors);
254
Mathieu Chartier98671c32014-08-20 10:04:08 -0700255 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 return -1;
257 }
258
259 struct cmsghdr *cmsg;
260 int countFds = outboundFds == NULL ? 0 : env->GetArrayLength(outboundFds);
261 int fds[countFds];
262 char msgbuf[CMSG_SPACE(countFds)];
263
264 // Add any pending outbound file descriptors to the message
265 if (outboundFds != NULL) {
266
Mathieu Chartier98671c32014-08-20 10:04:08 -0700267 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 return -1;
269 }
270
271 for (int i = 0; i < countFds; i++) {
272 jobject fdObject = env->GetObjectArrayElement(outboundFds, i);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700273 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 return -1;
275 }
276
277 fds[i] = jniGetFDFromFileDescriptor(env, fdObject);
Mathieu Chartier98671c32014-08-20 10:04:08 -0700278 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 return -1;
280 }
281 }
282
283 // See "man cmsg" really
284 msg.msg_control = msgbuf;
285 msg.msg_controllen = sizeof msgbuf;
286 cmsg = CMSG_FIRSTHDR(&msg);
287 cmsg->cmsg_level = SOL_SOCKET;
288 cmsg->cmsg_type = SCM_RIGHTS;
289 cmsg->cmsg_len = CMSG_LEN(sizeof fds);
290 memcpy(CMSG_DATA(cmsg), fds, sizeof fds);
291 }
292
293 // We only write our msg_control during the first write
294 while (len > 0) {
295 struct iovec iv;
296 memset(&iv, 0, sizeof(iv));
297
298 iv.iov_base = buffer;
299 iv.iov_len = len;
300
301 msg.msg_iov = &iv;
302 msg.msg_iovlen = 1;
Elliott Hughes69a017b2011-04-08 14:10:28 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 do {
305 ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
306 } while (ret < 0 && errno == EINTR);
307
308 if (ret < 0) {
309 jniThrowIOException(env, errno);
310 return -1;
311 }
312
313 buffer += ret;
314 len -= ret;
315
316 // Wipes out any msg_control too
317 memset(&msg, 0, sizeof(msg));
318 }
319
320 return 0;
321}
322
323static jint socket_read (JNIEnv *env, jobject object, jobject fileDescriptor)
324{
325 int fd;
326 int err;
327
328 if (fileDescriptor == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700329 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 return (jint)-1;
331 }
332
333 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
334
Mathieu Chartier98671c32014-08-20 10:04:08 -0700335 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 return (jint)0;
337 }
338
339 unsigned char buf;
340
341 err = socket_read_all(env, object, fd, &buf, 1);
342
343 if (err < 0) {
344 jniThrowIOException(env, errno);
345 return (jint)0;
346 }
347
348 if (err == 0) {
349 // end of file
350 return (jint)-1;
351 }
352
353 return (jint)buf;
354}
355
Elliott Hughes69a017b2011-04-08 14:10:28 -0700356static jint socket_readba (JNIEnv *env, jobject object,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 jbyteArray buffer, jint off, jint len, jobject fileDescriptor)
358{
359 int fd;
360 jbyte* byteBuffer;
361 int ret;
362
363 if (fileDescriptor == NULL || buffer == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700364 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 return (jint)-1;
366 }
367
368 if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) {
369 jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
370 return (jint)-1;
371 }
372
373 if (len == 0) {
374 // because socket_read_all returns 0 on EOF
375 return 0;
376 }
377
378 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
379
Mathieu Chartier98671c32014-08-20 10:04:08 -0700380 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 return (jint)-1;
382 }
383
384 byteBuffer = env->GetByteArrayElements(buffer, NULL);
385
386 if (NULL == byteBuffer) {
387 // an exception will have been thrown
388 return (jint)-1;
389 }
390
Elliott Hughes69a017b2011-04-08 14:10:28 -0700391 ret = socket_read_all(env, object,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 fd, byteBuffer + off, len);
393
394 // A return of -1 above means an exception is pending
395
396 env->ReleaseByteArrayElements(buffer, byteBuffer, 0);
397
398 return (jint) ((ret == 0) ? -1 : ret);
399}
400
Elliott Hughes69a017b2011-04-08 14:10:28 -0700401static void socket_write (JNIEnv *env, jobject object,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 jint b, jobject fileDescriptor)
403{
404 int fd;
405 int err;
406
407 if (fileDescriptor == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700408 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 return;
410 }
411
412 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
413
Mathieu Chartier98671c32014-08-20 10:04:08 -0700414 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 return;
416 }
417
418 err = socket_write_all(env, object, fd, &b, 1);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800419 UNUSED(err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 // A return of -1 above means an exception is pending
421}
422
Elliott Hughes69a017b2011-04-08 14:10:28 -0700423static void socket_writeba (JNIEnv *env, jobject object,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 jbyteArray buffer, jint off, jint len, jobject fileDescriptor)
425{
426 int fd;
427 int err;
428 jbyte* byteBuffer;
429
430 if (fileDescriptor == NULL || buffer == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700431 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 return;
433 }
434
435 if (off < 0 || len < 0 || (off + len) > env->GetArrayLength(buffer)) {
436 jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
437 return;
438 }
439
440 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
441
Mathieu Chartier98671c32014-08-20 10:04:08 -0700442 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 return;
444 }
445
446 byteBuffer = env->GetByteArrayElements(buffer,NULL);
447
448 if (NULL == byteBuffer) {
449 // an exception will have been thrown
450 return;
451 }
452
Elliott Hughes69a017b2011-04-08 14:10:28 -0700453 err = socket_write_all(env, object, fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 byteBuffer + off, len);
Andreas Gampe0f0b4912014-11-12 08:03:48 -0800455 UNUSED(err);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 // A return of -1 above means an exception is pending
457
458 env->ReleaseByteArrayElements(buffer, byteBuffer, JNI_ABORT);
459}
460
Elliott Hughes69a017b2011-04-08 14:10:28 -0700461static jobject socket_get_peer_credentials(JNIEnv *env,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 jobject object, jobject fileDescriptor)
463{
464 int err;
465 int fd;
466
467 if (fileDescriptor == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700468 jniThrowNullPointerException(env, NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 return NULL;
470 }
471
472 fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
473
Mathieu Chartier98671c32014-08-20 10:04:08 -0700474 if (env->ExceptionCheck()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 return NULL;
476 }
477
478 struct ucred creds;
479
480 memset(&creds, 0, sizeof(creds));
481 socklen_t szCreds = sizeof(creds);
482
Elliott Hughes69a017b2011-04-08 14:10:28 -0700483 err = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484
485 if (err < 0) {
486 jniThrowIOException(env, errno);
487 return NULL;
488 }
489
490 if (szCreds == 0) {
491 return NULL;
492 }
493
Elliott Hughes69a017b2011-04-08 14:10:28 -0700494 return env->NewObject(class_Credentials, method_CredentialsInit,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 creds.pid, creds.uid, creds.gid);
496}
497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498/*
499 * JNI registration.
500 */
Daniel Micay76f6a862015-09-19 17:31:01 -0400501static const JNINativeMethod gMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 /* name, signature, funcPtr */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
504 (void*)socket_connect_local},
505 {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
507 {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
508 {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
509 {"write_native", "(ILjava/io/FileDescriptor;)V", (void*) socket_write},
Elliott Hughes69a017b2011-04-08 14:10:28 -0700510 {"getPeerCredentials_native",
511 "(Ljava/io/FileDescriptor;)Landroid/net/Credentials;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 (void*) socket_get_peer_credentials}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513};
514
515int register_android_net_LocalSocketImpl(JNIEnv *env)
516{
517 jclass clazz;
518
519 clazz = env->FindClass("android/net/LocalSocketImpl");
520
521 if (clazz == NULL) {
522 goto error;
523 }
524
Elliott Hughes69a017b2011-04-08 14:10:28 -0700525 field_inboundFileDescriptors = env->GetFieldID(clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 "inboundFileDescriptors", "[Ljava/io/FileDescriptor;");
527
528 if (field_inboundFileDescriptors == NULL) {
529 goto error;
530 }
531
Elliott Hughes69a017b2011-04-08 14:10:28 -0700532 field_outboundFileDescriptors = env->GetFieldID(clazz,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 "outboundFileDescriptors", "[Ljava/io/FileDescriptor;");
534
535 if (field_outboundFileDescriptors == NULL) {
536 goto error;
537 }
538
539 class_Credentials = env->FindClass("android/net/Credentials");
Elliott Hughes69a017b2011-04-08 14:10:28 -0700540
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 if (class_Credentials == NULL) {
542 goto error;
543 }
544
545 class_Credentials = (jclass)env->NewGlobalRef(class_Credentials);
546
547 class_FileDescriptor = env->FindClass("java/io/FileDescriptor");
548
549 if (class_FileDescriptor == NULL) {
550 goto error;
551 }
552
553 class_FileDescriptor = (jclass)env->NewGlobalRef(class_FileDescriptor);
554
Elliott Hughes69a017b2011-04-08 14:10:28 -0700555 method_CredentialsInit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 = env->GetMethodID(class_Credentials, "<init>", "(III)V");
557
558 if (method_CredentialsInit == NULL) {
559 goto error;
560 }
561
562 return jniRegisterNativeMethods(env,
563 "android/net/LocalSocketImpl", gMethods, NELEM(gMethods));
564
565error:
Steve Block3762c312012-01-06 19:20:56 +0000566 ALOGE("Error registering android.net.LocalSocketImpl");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 return -1;
568}
569
570};