1 /* //device/libs/android_runtime/android_util_FileObserver.cpp
3 ** Copyright 2006, The Android Open Source Project
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
20 #include "utils/Log.h"
21 #include "utils/misc.h"
22 #include "core_jni_helpers.h"
29 #include <sys/ioctl.h>
32 #if defined(__linux__)
33 #include <sys/inotify.h>
38 static jmethodID method_onEvent;
40 static jint android_os_fileobserver_init(JNIEnv* env, jobject object)
42 #if defined(__linux__)
43 return (jint)inotify_init();
49 static void android_os_fileobserver_observe(JNIEnv* env, jobject object, jint fd)
51 #if defined(__linux__)
54 struct inotify_event* event;
59 int num_bytes = read(fd, event_buf, sizeof(event_buf));
61 if (num_bytes < (int)sizeof(*event))
66 ALOGE("***** ERROR! android_os_fileobserver_observe() got a short event!");
70 while (num_bytes >= (int)sizeof(*event))
73 event = (struct inotify_event *)(event_buf + event_pos);
79 path = env->NewStringUTF(event->name);
82 env->CallVoidMethod(object, method_onEvent, event->wd, event->mask, path);
83 if (env->ExceptionCheck()) {
84 env->ExceptionDescribe();
85 env->ExceptionClear();
89 env->DeleteLocalRef(path);
92 event_size = sizeof(*event) + event->len;
93 num_bytes -= event_size;
94 event_pos += event_size;
101 static jint android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd, jstring pathString, jint mask)
105 #if defined(__linux__)
109 const char* path = env->GetStringUTFChars(pathString, NULL);
111 res = inotify_add_watch(fd, path, mask);
113 env->ReleaseStringUTFChars(pathString, path);
121 static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
123 #if defined(__linux__)
125 inotify_rm_watch((int)fd, (uint32_t)wfd);
130 static JNINativeMethod sMethods[] = {
131 /* name, signature, funcPtr */
132 { "init", "()I", (void*)android_os_fileobserver_init },
133 { "observe", "(I)V", (void*)android_os_fileobserver_observe },
134 { "startWatching", "(ILjava/lang/String;I)I", (void*)android_os_fileobserver_startWatching },
135 { "stopWatching", "(II)V", (void*)android_os_fileobserver_stopWatching }
139 int register_android_os_FileObserver(JNIEnv* env)
141 jclass clazz = FindClassOrDie(env, "android/os/FileObserver$ObserverThread");
143 method_onEvent = GetMethodIDOrDie(env, clazz, "onEvent", "(IILjava/lang/String;)V");
145 return RegisterMethodsOrDie(env, "android/os/FileObserver$ObserverThread", sMethods,
149 } /* namespace android */