blob: 66aea9b066cc3e08f8829ecfdf60fbf07e09ca7f [file] [log] [blame]
Zim3e45d9b2019-08-19 21:14:14 +01001/*
2 * Copyright (C) 2019 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 specic language governing permissions and
14 * limitations under the License.
15 */
16
17// Need to use LOGE_EX.
Zim7e0d3142019-10-17 21:06:12 +010018#define LOG_TAG "FuseDaemonJNI"
Zim3e45d9b2019-08-19 21:14:14 +010019
shafik8b57cd52019-09-06 10:51:29 +010020#include <nativehelper/scoped_utf_chars.h>
Zim3e45d9b2019-08-19 21:14:14 +010021
22#include <string>
23
shafik8b57cd52019-09-06 10:51:29 +010024#include "FuseDaemon.h"
Narayan Kamathde3fe172020-02-18 12:14:51 +000025#include "MediaProviderWrapper.h"
shafik8b57cd52019-09-06 10:51:29 +010026#include "android-base/logging.h"
Zim3e45d9b2019-08-19 21:14:14 +010027
28namespace mediaprovider {
29namespace {
30
31constexpr const char* CLASS_NAME = "com/android/providers/media/fuse/FuseDaemon";
32static jclass gFuseDaemonClass;
33
Zimedbe69e2019-12-13 18:49:36 +000034jlong com_android_providers_media_FuseDaemon_new(JNIEnv* env, jobject self,
35 jobject media_provider) {
Narayan Kamath88203dc2019-08-30 17:19:38 +010036 LOG(DEBUG) << "Creating the FUSE daemon...";
Zimedbe69e2019-12-13 18:49:36 +000037 return reinterpret_cast<jlong>(new fuse::FuseDaemon(env, media_provider));
Zim3e45d9b2019-08-19 21:14:14 +010038}
39
shafik8b57cd52019-09-06 10:51:29 +010040void com_android_providers_media_FuseDaemon_start(JNIEnv* env, jobject self, jlong java_daemon,
Zim7c8712d2019-10-03 21:01:26 +010041 jint fd, jstring java_path) {
Narayan Kamath88203dc2019-08-30 17:19:38 +010042 LOG(DEBUG) << "Starting the FUSE daemon...";
Zim3e45d9b2019-08-19 21:14:14 +010043 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
44
Zim7c8712d2019-10-03 21:01:26 +010045 ScopedUtfChars utf_chars_path(env, java_path);
46 if (!utf_chars_path.c_str()) {
Zim3e45d9b2019-08-19 21:14:14 +010047 return;
48 }
Zim3e45d9b2019-08-19 21:14:14 +010049
Zimedbe69e2019-12-13 18:49:36 +000050 daemon->Start(fd, utf_chars_path.c_str());
Zim3e45d9b2019-08-19 21:14:14 +010051}
52
Zimd0435b22020-03-05 13:52:51 +000053bool com_android_providers_media_FuseDaemon_is_started(JNIEnv* env, jobject self,
54 jlong java_daemon) {
55 LOG(DEBUG) << "Checking if FUSE daemon started...";
56 const fuse::FuseDaemon* daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
57 return daemon->IsStarted();
58}
59
shafik8b57cd52019-09-06 10:51:29 +010060void com_android_providers_media_FuseDaemon_delete(JNIEnv* env, jobject self, jlong java_daemon) {
Narayan Kamath88203dc2019-08-30 17:19:38 +010061 LOG(DEBUG) << "Destroying the FUSE daemon...";
Zim3e45d9b2019-08-19 21:14:14 +010062 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
63 delete daemon;
64}
65
Zimedbe69e2019-12-13 18:49:36 +000066jboolean com_android_providers_media_FuseDaemon_should_open_with_fuse(JNIEnv* env, jobject self,
67 jlong java_daemon,
68 jstring java_path,
69 jboolean for_read, jint fd) {
70 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
71 if (daemon) {
72 ScopedUtfChars utf_chars_path(env, java_path);
73 if (!utf_chars_path.c_str()) {
74 // TODO(b/145741852): Throw exception
75 return JNI_FALSE;
76 }
77
78 return daemon->ShouldOpenWithFuse(fd, for_read, utf_chars_path.c_str());
79 }
80 // TODO(b/145741852): Throw exception
81 return JNI_FALSE;
82}
83
Zima76c3492020-02-19 01:23:26 +000084void com_android_providers_media_FuseDaemon_invalidate_fuse_dentry_cache(JNIEnv* env, jobject self,
85 jlong java_daemon,
86 jstring java_path) {
87 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
88 if (daemon) {
89 ScopedUtfChars utf_chars_path(env, java_path);
90 if (!utf_chars_path.c_str()) {
91 // TODO(b/145741152): Throw exception
92 return;
93 }
94
Colin Cross915ad6a2020-04-03 18:19:07 -070095 CHECK(pthread_getspecific(fuse::MediaProviderWrapper::gJniEnvKey) == nullptr);
Zima76c3492020-02-19 01:23:26 +000096 daemon->InvalidateFuseDentryCache(utf_chars_path.c_str());
97 }
98 // TODO(b/145741152): Throw exception
99}
100
Zimc0e65bd2020-03-09 15:22:59 +0000101bool com_android_providers_media_FuseDaemon_is_fuse_thread(JNIEnv* env, jclass clazz) {
102 LOG(VERBOSE) << "Checking if FUSE thread...";
103 return pthread_getspecific(fuse::MediaProviderWrapper::gJniEnvKey) != nullptr;
104}
105
Zim3e45d9b2019-08-19 21:14:14 +0100106const JNINativeMethod methods[] = {
Zim7c8712d2019-10-03 21:01:26 +0100107 {"native_new", "(Lcom/android/providers/media/MediaProvider;)J",
108 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_new)},
109 {"native_start", "(JILjava/lang/String;)V",
110 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_start)},
Zim7c8712d2019-10-03 21:01:26 +0100111 {"native_delete", "(J)V",
Zimedbe69e2019-12-13 18:49:36 +0000112 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_delete)},
113 {"native_should_open_with_fuse", "(JLjava/lang/String;ZI)Z",
Zima76c3492020-02-19 01:23:26 +0000114 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_should_open_with_fuse)},
Zimc0e65bd2020-03-09 15:22:59 +0000115 {"native_is_fuse_thread", "()Z",
116 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_is_fuse_thread)},
Zimd0435b22020-03-05 13:52:51 +0000117 {"native_is_started", "(J)Z",
118 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_is_started)},
Zima76c3492020-02-19 01:23:26 +0000119 {"native_invalidate_fuse_dentry_cache", "(JLjava/lang/String;)V",
120 reinterpret_cast<void*>(
121 com_android_providers_media_FuseDaemon_invalidate_fuse_dentry_cache)}};
Zim3e45d9b2019-08-19 21:14:14 +0100122} // namespace
123
Narayan Kamathde3fe172020-02-18 12:14:51 +0000124void register_android_providers_media_FuseDaemon(JavaVM* vm, JNIEnv* env) {
Zim3e45d9b2019-08-19 21:14:14 +0100125 gFuseDaemonClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass(CLASS_NAME)));
Narayan Kamath88203dc2019-08-30 17:19:38 +0100126
127 if (gFuseDaemonClass == nullptr) {
128 LOG(FATAL) << "Unable to find class : " << CLASS_NAME;
129 }
130
shafik8b57cd52019-09-06 10:51:29 +0100131 if (env->RegisterNatives(gFuseDaemonClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
Narayan Kamath88203dc2019-08-30 17:19:38 +0100132 LOG(FATAL) << "Unable to register native methods";
133 }
Narayan Kamathde3fe172020-02-18 12:14:51 +0000134
135 fuse::MediaProviderWrapper::OneTimeInit(vm);
Zim3e45d9b2019-08-19 21:14:14 +0100136}
137} // namespace mediaprovider