OSDN Git Service

Delay hiding the cast icon for 3 seconds. DO NOT MERGE am: 1044e162c3 am: b1de85487a...
[android-x86/frameworks-base.git] / core / jni / android_util_FileObserver.cpp
1 /* //device/libs/android_runtime/android_util_FileObserver.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
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 
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0 
10 **
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.
16 */
17
18 #include "JNIHelp.h"
19 #include "jni.h"
20 #include "utils/Log.h"
21 #include "utils/misc.h"
22 #include "core_jni_helpers.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdint.h>
28 #include <fcntl.h>
29 #include <sys/ioctl.h>
30 #include <errno.h>
31
32 #if defined(__linux__)
33 #include <sys/inotify.h>
34 #endif
35
36 namespace android {
37
38 static jmethodID method_onEvent;
39
40 static jint android_os_fileobserver_init(JNIEnv* env, jobject object)
41 {
42 #if defined(__linux__)
43     return (jint)inotify_init();
44 #else
45     return -1;
46 #endif
47 }
48
49 static void android_os_fileobserver_observe(JNIEnv* env, jobject object, jint fd)
50 {
51 #if defined(__linux__)
52
53     char event_buf[512];
54     struct inotify_event* event;
55
56     while (1)
57     {
58         int event_pos = 0;
59         int num_bytes = read(fd, event_buf, sizeof(event_buf));
60
61         if (num_bytes < (int)sizeof(*event))
62         {
63             if (errno == EINTR)
64                 continue;
65
66             ALOGE("***** ERROR! android_os_fileobserver_observe() got a short event!");
67             return;
68         }
69
70         while (num_bytes >= (int)sizeof(*event))
71         {
72             int event_size;
73             event = (struct inotify_event *)(event_buf + event_pos);
74
75             jstring path = NULL;
76
77             if (event->len > 0)
78             {
79                 path = env->NewStringUTF(event->name);
80             }
81
82             env->CallVoidMethod(object, method_onEvent, event->wd, event->mask, path);
83             if (env->ExceptionCheck()) {
84                 env->ExceptionDescribe();
85                 env->ExceptionClear();
86             }
87             if (path != NULL)
88             {
89                 env->DeleteLocalRef(path);
90             }
91
92             event_size = sizeof(*event) + event->len;
93             num_bytes -= event_size;
94             event_pos += event_size;
95         }
96     }
97
98 #endif
99 }
100
101 static jint android_os_fileobserver_startWatching(JNIEnv* env, jobject object, jint fd, jstring pathString, jint mask)
102 {
103     int res = -1;
104
105 #if defined(__linux__)
106
107     if (fd >= 0)
108     {
109         const char* path = env->GetStringUTFChars(pathString, NULL);
110
111         res = inotify_add_watch(fd, path, mask);
112
113         env->ReleaseStringUTFChars(pathString, path);
114     }
115
116 #endif
117
118     return res;
119 }
120
121 static void android_os_fileobserver_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
122 {
123 #if defined(__linux__)
124
125     inotify_rm_watch((int)fd, (uint32_t)wfd);
126
127 #endif
128 }
129
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 }
136
137 };
138
139 int register_android_os_FileObserver(JNIEnv* env)
140 {
141     jclass clazz = FindClassOrDie(env, "android/os/FileObserver$ObserverThread");
142
143     method_onEvent = GetMethodIDOrDie(env, clazz, "onEvent", "(IILjava/lang/String;)V");
144
145     return RegisterMethodsOrDie(env, "android/os/FileObserver$ObserverThread", sMethods,
146                                 NELEM(sMethods));
147 }
148
149 } /* namespace android */