blob: 9de00b6b8c6b9e6a24b55ee158d92dbee8809a59 [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
shafik8b57cd52019-09-06 10:51:29 +010053void com_android_providers_media_FuseDaemon_delete(JNIEnv* env, jobject self, jlong java_daemon) {
Narayan Kamath88203dc2019-08-30 17:19:38 +010054 LOG(DEBUG) << "Destroying the FUSE daemon...";
Zim3e45d9b2019-08-19 21:14:14 +010055 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
56 delete daemon;
57}
58
Zimedbe69e2019-12-13 18:49:36 +000059jboolean com_android_providers_media_FuseDaemon_should_open_with_fuse(JNIEnv* env, jobject self,
60 jlong java_daemon,
61 jstring java_path,
62 jboolean for_read, jint fd) {
63 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
64 if (daemon) {
65 ScopedUtfChars utf_chars_path(env, java_path);
66 if (!utf_chars_path.c_str()) {
67 // TODO(b/145741852): Throw exception
68 return JNI_FALSE;
69 }
70
71 return daemon->ShouldOpenWithFuse(fd, for_read, utf_chars_path.c_str());
72 }
73 // TODO(b/145741852): Throw exception
74 return JNI_FALSE;
75}
76
Zima76c3492020-02-19 01:23:26 +000077void com_android_providers_media_FuseDaemon_invalidate_fuse_dentry_cache(JNIEnv* env, jobject self,
78 jlong java_daemon,
79 jstring java_path) {
80 fuse::FuseDaemon* const daemon = reinterpret_cast<fuse::FuseDaemon*>(java_daemon);
81 if (daemon) {
82 ScopedUtfChars utf_chars_path(env, java_path);
83 if (!utf_chars_path.c_str()) {
84 // TODO(b/145741152): Throw exception
85 return;
86 }
87
88 daemon->InvalidateFuseDentryCache(utf_chars_path.c_str());
89 }
90 // TODO(b/145741152): Throw exception
91}
92
Zim3e45d9b2019-08-19 21:14:14 +010093const JNINativeMethod methods[] = {
Zim7c8712d2019-10-03 21:01:26 +010094 {"native_new", "(Lcom/android/providers/media/MediaProvider;)J",
95 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_new)},
96 {"native_start", "(JILjava/lang/String;)V",
97 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_start)},
Zim7c8712d2019-10-03 21:01:26 +010098 {"native_delete", "(J)V",
Zimedbe69e2019-12-13 18:49:36 +000099 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_delete)},
100 {"native_should_open_with_fuse", "(JLjava/lang/String;ZI)Z",
Zima76c3492020-02-19 01:23:26 +0000101 reinterpret_cast<void*>(com_android_providers_media_FuseDaemon_should_open_with_fuse)},
102 {"native_invalidate_fuse_dentry_cache", "(JLjava/lang/String;)V",
103 reinterpret_cast<void*>(
104 com_android_providers_media_FuseDaemon_invalidate_fuse_dentry_cache)}};
Zim3e45d9b2019-08-19 21:14:14 +0100105} // namespace
106
Narayan Kamathde3fe172020-02-18 12:14:51 +0000107void register_android_providers_media_FuseDaemon(JavaVM* vm, JNIEnv* env) {
Zim3e45d9b2019-08-19 21:14:14 +0100108 gFuseDaemonClass = static_cast<jclass>(env->NewGlobalRef(env->FindClass(CLASS_NAME)));
Narayan Kamath88203dc2019-08-30 17:19:38 +0100109
110 if (gFuseDaemonClass == nullptr) {
111 LOG(FATAL) << "Unable to find class : " << CLASS_NAME;
112 }
113
shafik8b57cd52019-09-06 10:51:29 +0100114 if (env->RegisterNatives(gFuseDaemonClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
Narayan Kamath88203dc2019-08-30 17:19:38 +0100115 LOG(FATAL) << "Unable to register native methods";
116 }
Narayan Kamathde3fe172020-02-18 12:14:51 +0000117
118 fuse::MediaProviderWrapper::OneTimeInit(vm);
Zim3e45d9b2019-08-19 21:14:14 +0100119}
120} // namespace mediaprovider