198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood/*
298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
398ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood *
498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * you may not use this file except in compliance with the License.
698ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * You may obtain a copy of the License at
798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood *
898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
998ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood *
1098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * Unless required by applicable law or agreed to in writing, software
1198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
1298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1398ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * See the License for the specific language governing permissions and
1498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood * limitations under the License.
1598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood */
1698ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
1798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#define LOG_TAG "MtpServerJNI"
1898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include "utils/Log.h"
1998ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
2098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <stdio.h>
2198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <assert.h>
2298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <limits.h>
2398ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <unistd.h>
2498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <fcntl.h>
2598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include <utils/threads.h>
2698ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
2798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include "jni.h"
2898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include "JNIHelp.h"
2998ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include "android_runtime/AndroidRuntime.h"
30dad69277b7fdcc2759bec5a35ac45dae8f61ec9bMike Lockwood#include "private/android_filesystem_config.h"
3198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
3298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood#include "MtpServer.h"
33467ca0de6d7fd55787a37de9dfd7e5325e1c3c6fMike Lockwood#include "MtpStorage.h"
3498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
3581ea83d10883886013bc95eac2fe032acf1e7aa9Mike Lockwoodusing namespace android;
3698ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
37dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood// MtpServer fields
38dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwoodstatic jfieldID field_MtpServer_nativeContext;
39b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
40b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood// MtpStorage fields
41b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic jfieldID field_MtpStorage_storageId;
42b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic jfieldID field_MtpStorage_path;
43b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic jfieldID field_MtpStorage_description;
44b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic jfieldID field_MtpStorage_reserveSpace;
4551690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwoodstatic jfieldID field_MtpStorage_removable;
467a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwoodstatic jfieldID field_MtpStorage_maxFileSize;
47b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
48b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic Mutex sMutex;
49b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
5098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood// ----------------------------------------------------------------------------
5198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
520cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood// in android_mtp_MtpDatabase.cpp
53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodextern MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database);
5498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
55dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwoodstatic inline MtpServer* getMtpServer(JNIEnv *env, jobject thiz) {
56dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    return (MtpServer*)env->GetIntField(thiz, field_MtpServer_nativeContext);
5798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood}
5898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
5998ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwoodstatic void
607d40d42a364f520da853b41956b0a18ed172491bMike Lockwoodandroid_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, jboolean usePtp)
6198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood{
62dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    int fd = open("/dev/mtp_usb", O_RDWR);
63dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (fd >= 0) {
64dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        MtpServer* server = new MtpServer(fd, getMtpDatabase(env, javaDatabase),
65dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood                usePtp, AID_MEDIA_RW, 0664, 0775);
66dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        env->SetIntField(thiz, field_MtpServer_nativeContext, (int)server);
67dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    } else {
683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("could not open MTP driver, errno: %d", errno);
69dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    }
7098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood}
7198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
7298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwoodstatic void
73dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwoodandroid_mtp_MtpServer_run(JNIEnv *env, jobject thiz)
7498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood{
75dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
76dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server)
77dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        server->run();
78dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    else
793762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in run");
8098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood}
8198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
8298ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwoodstatic void
83dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwoodandroid_mtp_MtpServer_cleanup(JNIEnv *env, jobject thiz)
8498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood{
85dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    Mutex::Autolock autoLock(sMutex);
86dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood
87dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
88dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server) {
89dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        delete server;
90dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        env->SetIntField(thiz, field_MtpServer_nativeContext, 0);
91dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    } else {
923762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in cleanup");
93071b2b6739c83d3de806cda5d7be2aba33fde1afMike Lockwood    }
9498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood}
9598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
96be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwoodstatic void
970cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpServer_send_object_added(JNIEnv *env, jobject thiz, jint handle)
98be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood{
99dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    Mutex::Autolock autoLock(sMutex);
100dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood
101dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
102dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server)
103dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        server->sendObjectAdded(handle);
104dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    else
1053762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in send_object_added");
106be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood}
107be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood
108be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwoodstatic void
1090cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodandroid_mtp_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle)
110be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood{
111dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    Mutex::Autolock autoLock(sMutex);
112dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood
113dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
114dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server)
115dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        server->sendObjectRemoved(handle);
116dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    else
1173762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in send_object_removed");
118be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood}
119be125a50b41f15810145671e0fcbdaf13b363e03Mike Lockwood
120eabe8bfaf8c45289a4cfd880f4107d1a9b17e38bMike Lockwoodstatic void
121b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodandroid_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage)
12266e57f6aa9d206552e9b154bf00a17d6efae7fb0Mike Lockwood{
123dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    Mutex::Autolock autoLock(sMutex);
124dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood
125dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
126dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server) {
127b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        jint storageID = env->GetIntField(jstorage, field_MtpStorage_storageId);
128b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        jstring path = (jstring)env->GetObjectField(jstorage, field_MtpStorage_path);
129b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        jstring description = (jstring)env->GetObjectField(jstorage, field_MtpStorage_description);
130b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        jlong reserveSpace = env->GetLongField(jstorage, field_MtpStorage_reserveSpace);
13151690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwood        jboolean removable = env->GetBooleanField(jstorage, field_MtpStorage_removable);
1327a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood        jlong maxFileSize = env->GetLongField(jstorage, field_MtpStorage_maxFileSize);
133b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
134b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        const char *pathStr = env->GetStringUTFChars(path, NULL);
1353977472d9f3380a8323156dbc7d0090cf2f2d310James Dong        if (pathStr != NULL) {
1363977472d9f3380a8323156dbc7d0090cf2f2d310James Dong            const char *descriptionStr = env->GetStringUTFChars(description, NULL);
1373977472d9f3380a8323156dbc7d0090cf2f2d310James Dong            if (descriptionStr != NULL) {
1387a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood                MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr,
1397a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood                        reserveSpace, removable, maxFileSize);
140dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood                server->addStorage(storage);
1413977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                env->ReleaseStringUTFChars(path, pathStr);
1423977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                env->ReleaseStringUTFChars(description, descriptionStr);
1433977472d9f3380a8323156dbc7d0090cf2f2d310James Dong            } else {
1443977472d9f3380a8323156dbc7d0090cf2f2d310James Dong                env->ReleaseStringUTFChars(path, pathStr);
1453977472d9f3380a8323156dbc7d0090cf2f2d310James Dong            }
1463977472d9f3380a8323156dbc7d0090cf2f2d310James Dong        }
147b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    } else {
1483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in add_storage");
149b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
150b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood}
151b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
152b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodstatic void
153b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwoodandroid_mtp_MtpServer_remove_storage(JNIEnv *env, jobject thiz, jint storageId)
154b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood{
155dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    Mutex::Autolock autoLock(sMutex);
156dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood
157dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    MtpServer* server = getMtpServer(env, thiz);
158dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (server) {
159dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        MtpStorage* storage = server->getStorage(storageId);
160dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        if (storage) {
161dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood            server->removeStorage(storage);
162dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood            delete storage;
163dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        }
164dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    } else
1653762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("server is null in remove_storage");
16666e57f6aa9d206552e9b154bf00a17d6efae7fb0Mike Lockwood}
16766e57f6aa9d206552e9b154bf00a17d6efae7fb0Mike Lockwood
16898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood// ----------------------------------------------------------------------------
16998ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
17098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwoodstatic JNINativeMethod gMethods[] = {
1717d40d42a364f520da853b41956b0a18ed172491bMike Lockwood    {"native_setup",                "(Landroid/mtp/MtpDatabase;Z)V",
1720cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                                            (void *)android_mtp_MtpServer_setup},
173dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    {"native_run",                  "()V",  (void *)android_mtp_MtpServer_run},
174dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    {"native_cleanup",              "()V",  (void *)android_mtp_MtpServer_cleanup},
1750cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_send_object_added",    "(I)V", (void *)android_mtp_MtpServer_send_object_added},
1760cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    {"native_send_object_removed",  "(I)V", (void *)android_mtp_MtpServer_send_object_removed},
177b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    {"native_add_storage",          "(Landroid/mtp/MtpStorage;)V",
178b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood                                            (void *)android_mtp_MtpServer_add_storage},
179b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    {"native_remove_storage",       "(I)V", (void *)android_mtp_MtpServer_remove_storage},
18098ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood};
18198ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
1820cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodstatic const char* const kClassPathName = "android/mtp/MtpServer";
18398ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
1840cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodint register_android_mtp_MtpServer(JNIEnv *env)
18598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood{
18698ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood    jclass clazz;
18798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
188b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    clazz = env->FindClass("android/mtp/MtpStorage");
189b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    if (clazz == NULL) {
1903762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpStorage");
191b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        return -1;
192b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
193b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    field_MtpStorage_storageId = env->GetFieldID(clazz, "mStorageId", "I");
194b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    if (field_MtpStorage_storageId == NULL) {
1953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mStorageId");
196b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        return -1;
197b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
198b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    field_MtpStorage_path = env->GetFieldID(clazz, "mPath", "Ljava/lang/String;");
199b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    if (field_MtpStorage_path == NULL) {
2003762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mPath");
201b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        return -1;
202b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
203b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    field_MtpStorage_description = env->GetFieldID(clazz, "mDescription", "Ljava/lang/String;");
204b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    if (field_MtpStorage_description == NULL) {
2053762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mDescription");
206b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        return -1;
207b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
208b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    field_MtpStorage_reserveSpace = env->GetFieldID(clazz, "mReserveSpace", "J");
209b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    if (field_MtpStorage_reserveSpace == NULL) {
2103762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mReserveSpace");
21151690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwood        return -1;
21251690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwood    }
21351690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwood    field_MtpStorage_removable = env->GetFieldID(clazz, "mRemovable", "Z");
21451690544aaeee82b1c50232cd57d50038b77f0c4Mike Lockwood    if (field_MtpStorage_removable == NULL) {
2153762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mRemovable");
216b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood        return -1;
217b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood    }
2187a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood    field_MtpStorage_maxFileSize = env->GetFieldID(clazz, "mMaxFileSize", "J");
2197a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood    if (field_MtpStorage_maxFileSize == NULL) {
2203762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpStorage.mMaxFileSize");
2217a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood        return -1;
2227a59dd2ce33b46cbc73eef964ddb4272ea1da8d1Mike Lockwood    }
223b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood
2240cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood    clazz = env->FindClass("android/mtp/MtpServer");
22598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood    if (clazz == NULL) {
2263762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find android/mtp/MtpServer");
22798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood        return -1;
22898ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood    }
229dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    field_MtpServer_nativeContext = env->GetFieldID(clazz, "mNativeContext", "I");
230dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    if (field_MtpServer_nativeContext == NULL) {
2313762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Can't find MtpServer.mNativeContext");
232dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood        return -1;
233dcc31946f2b78be4bf95b1cace2e2c211f027e72Mike Lockwood    }
23498ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood
23598ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood    return AndroidRuntime::registerNativeMethods(env,
2360cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwood                "android/mtp/MtpServer", gMethods, NELEM(gMethods));
23798ef64e4a89ced79094d4ff3dc0123c1989f9e10Mike Lockwood}
238