1878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono/*
2878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * Copyright (C) 2016 The Android Open Source Project
3878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono *
4878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * Licensed under the Apache License, Version 2.0 (the "License");
5878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * you may not use this file except in compliance with the License.
6878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * You may obtain a copy of the License at
7878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono *
8878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono *      http://www.apache.org/licenses/LICENSE-2.0
9878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono *
10878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * Unless required by applicable law or agreed to in writing, software
11878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * distributed under the License is distributed on an "AS IS" BASIS,
12878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * See the License for the specific language governing permissions and
14878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono * limitations under the License.
15878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono */
16878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
17878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#define LOG_TAG "FuseAppLoopJNI"
18878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#define LOG_NDEBUG 0
19878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
20878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <stdlib.h>
21878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <sys/stat.h>
22878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
234f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono#include <map>
244f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono#include <memory>
254f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
26878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <android_runtime/Log.h>
27878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <android-base/logging.h>
28878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <android-base/unique_fd.h>
29878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <jni.h>
30878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <libappfuse/FuseAppLoop.h>
31878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include <nativehelper/ScopedLocalRef.h>
324f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono#include <nativehelper/ScopedPrimitiveArray.h>
33878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
34878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono#include "core_jni_helpers.h"
35878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
36878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirononamespace android {
37878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirononamespace {
38878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironoconstexpr const char* CLASS_NAME = "com/android/internal/os/FuseAppLoop";
39878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
40878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironojclass gFuseAppLoopClass;
414f156065c860d916b649e2b464e9405cafc732e9Daichi HironojmethodID gOnCommandMethod;
42878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi HironojmethodID gOnOpenMethod;
43878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
44878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironoclass Callback : public fuse::FuseAppLoopCallback {
45878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironoprivate:
464f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    typedef ScopedLocalRef<jbyteArray> LocalBytes;
47878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    JNIEnv* const mEnv;
48878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    jobject const mSelf;
494f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    std::map<uint64_t, std::unique_ptr<LocalBytes>> mBuffers;
50878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
51878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironopublic:
52878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    Callback(JNIEnv* env, jobject self) :
534f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        mEnv(env), mSelf(self) {}
54878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
554f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnLookup(uint64_t unique, uint64_t inode) override {
5677a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_LOOKUP, unique, inode, 0, 0, nullptr);
57878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
58878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
594f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnGetAttr(uint64_t unique, uint64_t inode) override {
6077a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_GETATTR, unique, inode, 0, 0, nullptr);
61878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
62878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
634f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnOpen(uint64_t unique, uint64_t inode) override {
644f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        const jbyteArray buffer = static_cast<jbyteArray>(mEnv->CallObjectMethod(
654f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono                mSelf, gOnOpenMethod, unique, inode));
664f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK(!mEnv->ExceptionCheck());
674f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        if (buffer == nullptr) {
684f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono            return;
694f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        }
70878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
714f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        mBuffers.insert(std::make_pair(inode, std::unique_ptr<LocalBytes>(
724f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono                new LocalBytes(mEnv, buffer))));
73878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
74878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
754f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnFsync(uint64_t unique, uint64_t inode) override {
7677a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_FSYNC, unique, inode, 0, 0, nullptr);
77878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
78878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
794f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnRelease(uint64_t unique, uint64_t inode) override {
804f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        mBuffers.erase(inode);
8177a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_RELEASE, unique, inode, 0, 0, nullptr);
82878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
83878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
844f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnRead(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size) override {
854f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxRead));
86878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
874f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        auto it = mBuffers.find(inode);
884f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK(it != mBuffers.end());
89878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
9077a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_READ, unique, inode, offset, size, it->second->get());
91878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
92878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
934f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    void OnWrite(uint64_t unique, uint64_t inode, uint64_t offset, uint32_t size,
944f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono            const void* buffer) override {
954f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK_LE(size, static_cast<uint32_t>(fuse::kFuseMaxWrite));
964f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
974f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        auto it = mBuffers.find(inode);
984f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK(it != mBuffers.end());
994f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1004f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        jbyteArray const javaBuffer = it->second->get();
101878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
1024f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        mEnv->SetByteArrayRegion(javaBuffer, 0, size, static_cast<const jbyte*>(buffer));
103878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono        CHECK(!mEnv->ExceptionCheck());
104878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
10577a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        CallOnCommand(FUSE_WRITE, unique, inode, offset, size, javaBuffer);
10677a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono    }
10777a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono
10877a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hironoprivate:
10977a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono    // Helper function to make sure we invoke CallVoidMethod with correct size of integer arguments.
11077a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono    void CallOnCommand(jint command, jlong unique, jlong inode, jlong offset, jint size,
11177a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono                       jobject bytes) {
11277a97cdba2903a6534fcabc1b8bc79b51aef54f5Daichi Hirono        mEnv->CallVoidMethod(mSelf, gOnCommandMethod, command, unique, inode, offset, size, bytes);
1134f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        CHECK(!mEnv->ExceptionCheck());
114878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
115878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono};
116878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
1174f156065c860d916b649e2b464e9405cafc732e9Daichi Hironojlong com_android_internal_os_FuseAppLoop_new(JNIEnv* env, jobject self, jint jfd) {
1184f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    return reinterpret_cast<jlong>(new fuse::FuseAppLoop(base::unique_fd(jfd)));
1194f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1204f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1214f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_delete(JNIEnv* env, jobject self, jlong ptr) {
1224f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    delete reinterpret_cast<fuse::FuseAppLoop*>(ptr);
1234f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1244f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1254f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_start(JNIEnv* env, jobject self, jlong ptr) {
126878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    Callback callback(env, self);
1274f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Start(&callback);
1284f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
129878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
1304f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replySimple(
1314f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jint result) {
1324f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplySimple(unique, result)) {
1334f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
134878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    }
1354f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
136878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
1374f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replyOpen(
1384f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong fh) {
1394f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyOpen(unique, fh)) {
1404f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
1414f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    }
1424f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1434f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1444f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replyLookup(
145d2229a65f53e7b9e9fc861ac300607a329153c4cDaichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
1464f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyLookup(unique, inode, size)) {
1474f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
1484f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    }
1494f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1504f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1514f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replyGetAttr(
152d2229a65f53e7b9e9fc861ac300607a329153c4cDaichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jlong inode, jlong size) {
1534f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyGetAttr(
1544f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono            unique, inode, size, S_IFREG | 0777)) {
1554f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
1564f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    }
1574f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1584f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1594f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replyWrite(
1604f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size) {
1614f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyWrite(unique, size)) {
1624f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
1634f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    }
1644f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono}
1654f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono
1664f156065c860d916b649e2b464e9405cafc732e9Daichi Hironovoid com_android_internal_os_FuseAppLoop_replyRead(
1674f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        JNIEnv* env, jobject self, jlong ptr, jlong unique, jint size, jbyteArray data) {
1684f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    ScopedByteArrayRO array(env, data);
1698cb610e2623bc791249170b5cf0989b06d385bbbRyo Hashimoto    CHECK_GE(size, 0);
1708cb610e2623bc791249170b5cf0989b06d385bbbRyo Hashimoto    CHECK_LE(static_cast<size_t>(size), array.size());
1714f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    if (!reinterpret_cast<fuse::FuseAppLoop*>(ptr)->ReplyRead(unique, size, array.get())) {
1724f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<fuse::FuseAppLoop*>(ptr)->Break();
1734f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    }
174878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono}
175878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
176878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironoconst JNINativeMethod methods[] = {
177878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    {
1784f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_new",
1794f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(I)J",
1804f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_new)
1814f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
1824f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
1834f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_delete",
1844f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(J)V",
1854f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_delete)
1864f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
1874f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
1884f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_start",
1894f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(J)V",
1904f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_start)
1914f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
1924f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
1934f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replySimple",
1944f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJI)V",
1954f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replySimple)
1964f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
1974f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
1984f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replyOpen",
1994f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJJ)V",
2004f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyOpen)
2014f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
2024f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
2034f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replyLookup",
2044f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJJJ)V",
2054f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyLookup)
2064f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
2074f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
2084f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replyGetAttr",
2094f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJJJ)V",
2104f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyGetAttr)
2114f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
2124f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
2134f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replyRead",
2144f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJI[B)V",
2154f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyRead)
2164f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
2174f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    {
2184f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "native_replyWrite",
2194f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        "(JJI)V",
2204f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono        reinterpret_cast<void*>(com_android_internal_os_FuseAppLoop_replyWrite)
2214f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    },
222878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono};
223878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono}  // namespace
224878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono
225878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hironoint register_com_android_internal_os_FuseAppLoop(JNIEnv* env) {
226878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    gFuseAppLoopClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME));
2274f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    gOnCommandMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onCommand", "(IJJJI[B)V");
2284f156065c860d916b649e2b464e9405cafc732e9Daichi Hirono    gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(JJ)[B");
229878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods));
230878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono    return 0;
231878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono}
232878e86f38f87cc5dc537ffc623b04f9a779fb080Daichi Hirono}  // namespace android
233