blob: 9a79412e540c8f2b086cb17ee0aa15d929ebfd1f [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
95 daemon->InvalidateFuseDentryCache(utf_chars_path.c_str());
96 }
97 // TODO(b/145741152): Throw exception
98}
99
Zimc0e65bd2020-03-09 15:22:59 +0000100bool com_android_providers_media_FuseDaemon_is_fuse_thread(JNIEnv* env, jclass clazz) {
101 LOG(VERBOSE) << "Checking if FUSE thread...";
102 return pthread_getspecific(fuse::MediaProviderWrapper::gJniEnvKey) != nullptr;
103}
104
Zim3e45d9b2019-08-19 21:14:14 +0100105const JNINativeMethod methods[] = {
Zim7c8712d2019-10-03 21:01:26 +0100106 {"native_new", "(Lcom/android/providers/media/MediaProvider;)J",
107 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_new)},
108 {"native_start", "(JILjava/lang/String;)V",
109 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_start)},
Zim7c8712d2019-10-03 21:01:26 +0100110 {"native_delete", "(J)V",
Zimedbe69e2019-12-13 18:49:36 +0000111 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_delete)},
112 {"native_should_open_with_fuse", "(JLjava/lang/String;ZI)Z",
Zima76c3492020-02-19 01:23:26 +0000113 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_should_open_with_fuse)},
Zimc0e65bd2020-03-09 15:22:59 +0000114 {"native_is_fuse_thread", "()Z",
115 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_is_fuse_thread)},
Zimd0435b22020-03-05 13:52:51 +0000116 {"native_is_started", "(J)Z",
117 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_is_started)},
Zima76c3492020-02-19 01:23:26 +0000118 {"native_invalidate_fuse_dentry_cache", "(JLjava/lang/String;)V",
119 reinterpret_cast<void*>(
120 com_android_providers_media_FuseDaemon_invalidate_fuse_dentry_cache)}};
Zim3e45d9b2019-08-19 21:14:14 +0100121} // namespace
122
Narayan Kamathde3fe172020-02-18 12:14:51 +0000123void register_android_providers_media_FuseDaemon(JavaVM* vm, JNIEnv* env) {
Zim3e45d9b2019-08-19 21:14:14 +0100124 gFuseDaemonClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass(CLASS_NAME)));
Narayan Kamath88203dc2019-08-30 17:19:38 +0100125
126 if (gFuseDaemonClass == nullptr) {
127 LOG(FATAL) << "Unable to find class : " << CLASS_NAME;
128 }
129
shafik8b57cd52019-09-06 10:51:29 +0100130 if (env->RegisterNatives(gFuseDaemonClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
Narayan Kamath88203dc2019-08-30 17:19:38 +0100131 LOG(FATAL) << "Unable to register native methods";
132 }
Narayan Kamathde3fe172020-02-18 12:14:51 +0000133
134 fuse::MediaProviderWrapper::OneTimeInit(vm);
Zim3e45d9b2019-08-19 21:14:14 +0100135}
136} // namespace mediaprovider