MtpDatabase.java revision 9a2046fb5ceeee4d5334274cbff15f1058bb3244
1d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/*
2d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Copyright (C) 2010 The Android Open Source Project
3d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
4d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
5d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * you may not use this file except in compliance with the License.
6d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * You may obtain a copy of the License at
7d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
8d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
9d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood *
10d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * Unless required by applicable law or agreed to in writing, software
11d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
12d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * See the License for the specific language governing permissions and
14d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * limitations under the License.
15d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */
16d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
17d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpackage android.media;
18d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
19d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.content.Context;
20d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodimport android.content.ContentValues;
21d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.content.IContentProvider;
22d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.database.Cursor;
23d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.net.Uri;
24d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.os.RemoteException;
259a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.MediaStore.Audio;
269a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.MediaStore.MediaColumns;
27d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.provider.MediaStore.MtpObjects;
289a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.Mtp;
29d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.util.Log;
30d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
31d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/**
32d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * {@hide}
33d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */
34d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic class MtpDatabase {
35d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
36d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String TAG = "MtpDatabase";
37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
38d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private final IContentProvider mMediaProvider;
39d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private final String mVolumeName;
40d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private final Uri mObjectsUri;
41d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
42b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    // FIXME - this should be passed in via the constructor
43b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private final int mStorageID = 0x00010001;
44b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String[] ID_PROJECTION = new String[] {
46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns._ID, // 0
47d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    };
48d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String[] PATH_SIZE_PROJECTION = new String[] {
49d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns._ID, // 0
50d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.DATA, // 1
51d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.SIZE, // 2
52d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    };
53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String[] OBJECT_INFO_PROJECTION = new String[] {
54d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns._ID, // 0
55d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.DATA, // 1
56d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.FORMAT, // 2
57d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.PARENT, // 3
58d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.SIZE, // 4
59d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            MtpObjects.ObjectColumns.DATE_MODIFIED, // 5
60d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    };
61d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String ID_WHERE = MtpObjects.ObjectColumns._ID + "=?";
62d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String PATH_WHERE = MtpObjects.ObjectColumns.DATA + "=?";
63d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String PARENT_WHERE = MtpObjects.ObjectColumns.PARENT + "=?";
64d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
65d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                                            + MtpObjects.ObjectColumns.FORMAT + "=?";
66d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
67d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    private final MediaScanner mMediaScanner;
68d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
69b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    // MTP property codes
70b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_STORAGE_ID = 0xDC01;
71b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_OBJECT_FORMAT = 0xDC02;
72b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_OBJECT_SIZE = 0xDC04;
73b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_OBJECT_FILE_NAME = 0xDC07;
74b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_DATE_MODIFIED = 0xDC09;
75b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_PROPERTY_PARENT_OBJECT = 0xDC0B;
76b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
77b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    // MTP response codes
78b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_RESPONSE_OK = 0x2001;
79b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_RESPONSE_GENERAL_ERROR = 0x2002;
80b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_RESPONSE_INVALID_OBJECT_HANDLE = 0x2009;
81b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood    private static final int MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED = 0xA80A;
82b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    static {
84d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        System.loadLibrary("media_jni");
85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
86d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
87d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    public MtpDatabase(Context context, String volumeName) {
88d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        native_setup();
89d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
90d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mMediaProvider = context.getContentResolver().acquireProvider("media");
91d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mVolumeName = volumeName;
92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        mObjectsUri = MtpObjects.getContentUri(volumeName);
93d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        mMediaScanner = new MediaScanner(context);
94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    @Override
97d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    protected void finalize() {
98d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        native_finalize();
99d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
101d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    private int beginSendObject(String path, int format, int parent,
102d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                         int storage, long size, long modified) {
103d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        ContentValues values = new ContentValues();
104d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        values.put(MtpObjects.ObjectColumns.DATA, path);
105d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        values.put(MtpObjects.ObjectColumns.FORMAT, format);
106d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        values.put(MtpObjects.ObjectColumns.PARENT, parent);
107d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        // storage is ignored for now
108d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        values.put(MtpObjects.ObjectColumns.SIZE, size);
109d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        values.put(MtpObjects.ObjectColumns.DATE_MODIFIED, modified);
110d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
111d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        try {
112d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            Uri uri = mMediaProvider.insert(mObjectsUri, values);
113d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            if (uri != null) {
114d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                return Integer.parseInt(uri.getPathSegments().get(2));
115d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            } else {
116d815f79766984fce499e147ecbacc01914683f74Mike Lockwood                return -1;
117d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            }
118d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        } catch (RemoteException e) {
119d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            Log.e(TAG, "RemoteException in beginSendObject", e);
120d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            return -1;
121d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        }
122d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    }
123d815f79766984fce499e147ecbacc01914683f74Mike Lockwood
124d815f79766984fce499e147ecbacc01914683f74Mike Lockwood    private void endSendObject(String path, int handle, int format, boolean succeeded) {
125d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        if (succeeded) {
1269a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            // handle abstract playlists separately
1279a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            // they do not exist in the file system so don't use the media scanner here
1289a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            if (format == Mtp.Object.FORMAT_ABSTRACT_AV_PLAYLIST) {
1299a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                // Strip Windows Media Player file extension
1309a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                if (path.endsWith(".pla")) {
1319a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    path = path.substring(0, path.length() - 4);
1329a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                }
1339a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1349a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                // extract name from path
1359a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                String name = path;
1369a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                int lastSlash = name.lastIndexOf('/');
1379a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                if (lastSlash >= 0) {
1389a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    name = name.substring(lastSlash + 1);
1399a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                }
1409a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
1419a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                ContentValues values = new ContentValues(1);
1429a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                values.put(Audio.Playlists.DATA, path);
1439a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                values.put(Audio.Playlists.NAME, name);
1449a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle);
1459a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                try {
1469a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    Uri uri = mMediaProvider.insert(Audio.Playlists.EXTERNAL_CONTENT_URI, values);
1479a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                } catch (RemoteException e) {
1489a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    Log.e(TAG, "RemoteException in endSendObject", e);
1499a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                }
1509a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            } else {
1519a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                Uri uri = mMediaScanner.scanMtpFile(path, mVolumeName, handle, format);
1529a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            }
153d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        } else {
154d815f79766984fce499e147ecbacc01914683f74Mike Lockwood            deleteFile(handle);
155d815f79766984fce499e147ecbacc01914683f74Mike Lockwood        }
156d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
157d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
158d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private int[] getObjectList(int storageID, int format, int parent) {
159d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        // we can ignore storageID until we support multiple storages
160d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Log.d(TAG, "getObjectList parent: " + parent);
161d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Cursor c = null;
162d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        try {
163d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (format != 0) {
164d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
165d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            PARENT_FORMAT_WHERE,
166d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            new String[] { Integer.toString(parent), Integer.toString(format) },
167d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                             null);
168d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            } else {
169d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
170d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            PARENT_WHERE, new String[] { Integer.toString(parent) }, null);
171d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
172d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c == null) {
173d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                Log.d(TAG, "null cursor");
174d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                return null;
175d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
176d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            int count = c.getCount();
177d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (count > 0) {
178d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                int[] result = new int[count];
179d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                for (int i = 0; i < count; i++) {
180d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                    c.moveToNext();
181d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                    result[i] = c.getInt(0);
182d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                }
183d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                Log.d(TAG, "returning " + result);
184d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                return result;
185d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
186d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } catch (RemoteException e) {
187d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            Log.e(TAG, "RemoteException in getObjectList", e);
188d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } finally {
189d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c != null) {
190d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                c.close();
191d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
192d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
193d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return null;
194d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
195d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
1967a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    private int getNumObjects(int storageID, int format, int parent) {
1977a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        // we can ignore storageID until we support multiple storages
1987a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        Log.d(TAG, "getObjectList parent: " + parent);
1997a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        Cursor c = null;
2007a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        try {
2017a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            if (format != 0) {
2027a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
2037a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                            PARENT_FORMAT_WHERE,
2047a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                            new String[] { Integer.toString(parent), Integer.toString(format) },
2057a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                             null);
2067a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            } else {
2077a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
2087a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                            PARENT_WHERE, new String[] { Integer.toString(parent) }, null);
2097a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            }
2107a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            if (c != null) {
2117a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                return c.getCount();
2127a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            }
2137a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        } catch (RemoteException e) {
2147a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            Log.e(TAG, "RemoteException in getNumObjects", e);
2157a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        } finally {
2167a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            if (c != null) {
2177a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood                c.close();
2187a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood            }
2197a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        }
2207a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood        return -1;
2217a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood    }
2227a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood
223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private int getObjectProperty(int handle, int property,
224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            long[] outIntValue, char[] outStringValue) {
225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Log.d(TAG, "getObjectProperty: " + property);
226b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        String column = null;
227b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        boolean isString = false;
228b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
229b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        switch (property) {
230b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_STORAGE_ID:
231b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                outIntValue[0] = mStorageID;
232b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                return MTP_RESPONSE_OK;
233b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_OBJECT_FORMAT:
234b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                column = MtpObjects.ObjectColumns.FORMAT;
235b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                break;
236b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_OBJECT_SIZE:
237b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                column = MtpObjects.ObjectColumns.SIZE;
238b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                break;
239b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_OBJECT_FILE_NAME:
240b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                column = MtpObjects.ObjectColumns.DATA;
241b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                isString = true;
242b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                break;
243b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_DATE_MODIFIED:
244b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                column = MtpObjects.ObjectColumns.DATE_MODIFIED;
245b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                break;
246b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            case MTP_PROPERTY_PARENT_OBJECT:
247b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                column = MtpObjects.ObjectColumns.PARENT;
248b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                break;
249b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            default:
250b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
251b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        }
252b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
253b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        Cursor c = null;
254b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        try {
255b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            // for now we are only reading properties from the "objects" table
256b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            c = mMediaProvider.query(mObjectsUri,
257b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                            new String [] { MtpObjects.ObjectColumns._ID, column },
258b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                            ID_WHERE, new String[] { Integer.toString(handle) }, null);
259b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            if (c != null && c.moveToNext()) {
260b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                if (isString) {
261b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    String value = c.getString(1);
262b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    int start = 0;
263b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood
264b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    if (property == MTP_PROPERTY_OBJECT_FILE_NAME) {
265b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                        // extract name from full path
266b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                        int lastSlash = value.lastIndexOf('/');
267b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                        if (lastSlash >= 0) {
268b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                            start = lastSlash + 1;
269b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                        }
270b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    }
271b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    int end = value.length();
272b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    if (end - start > 255) {
273b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                        end = start + 255;
274b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    }
275b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    value.getChars(start, end, outStringValue, 0);
276b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    outStringValue[end - start] = 0;
277b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                } else {
278b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                    outIntValue[0] = c.getLong(1);
279b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                }
280b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                return MTP_RESPONSE_OK;
281b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            }
282b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        } catch (Exception e) {
283b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            return MTP_RESPONSE_GENERAL_ERROR;
284b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        } finally {
285b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            if (c != null) {
286b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                c.close();
287b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood            }
288b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        }
289b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        // query failed if we get here
290b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
291d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
292d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
293d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
294d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                        char[] outName, long[] outSizeModified) {
295d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Log.d(TAG, "getObjectInfo: " + handle);
296d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Cursor c = null;
297d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        try {
298d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
299d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            ID_WHERE, new String[] {  Integer.toString(handle) }, null);
300d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c != null && c.moveToNext()) {
301b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood                outStorageFormatParent[0] = mStorageID;
302d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outStorageFormatParent[1] = c.getInt(2);
303d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outStorageFormatParent[2] = c.getInt(3);
304d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
305d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                // extract name from path
306d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                String path = c.getString(1);
307d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                int lastSlash = path.lastIndexOf('/');
308d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                int start = (lastSlash >= 0 ? lastSlash + 1 : 0);
309d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                int end = path.length();
310d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                if (end - start > 255) {
311d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                    end = start + 255;
312d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                }
313d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                path.getChars(start, end, outName, 0);
314d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outName[end - start] = 0;
315d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
316d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outSizeModified[0] = c.getLong(4);
317d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outSizeModified[1] = c.getLong(5);
318d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                return true;
319d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
320d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } catch (RemoteException e) {
321d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            Log.e(TAG, "RemoteException in getObjectProperty", e);
322d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } finally {
323d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c != null) {
324d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                c.close();
325d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
326d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
327d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        return false;
328d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
329d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
33059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLength) {
331d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Log.d(TAG, "getObjectFilePath: " + handle);
332d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Cursor c = null;
333d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        try {
334d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            c = mMediaProvider.query(mObjectsUri, PATH_SIZE_PROJECTION,
335d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                            ID_WHERE, new String[] {  Integer.toString(handle) }, null);
336d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c != null && c.moveToNext()) {
337d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                String path = c.getString(1);
338d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                path.getChars(0, path.length(), outFilePath, 0);
339d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outFilePath[path.length()] = 0;
340d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                outFileLength[0] = c.getLong(2);
34159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood                return MTP_RESPONSE_OK;
34259c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            } else {
34359c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood                return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
344d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
345d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } catch (RemoteException e) {
346d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            Log.e(TAG, "RemoteException in getObjectFilePath", e);
34759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            return MTP_RESPONSE_GENERAL_ERROR;
348d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } finally {
349d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            if (c != null) {
350d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood                c.close();
351d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            }
352d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
353d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
354d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
35559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood    private int deleteFile(int handle) {
356d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Log.d(TAG, "deleteFile: " + handle);
357d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        Uri uri = MtpObjects.getContentUri(mVolumeName, handle);
358d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        try {
35959c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            if (mMediaProvider.delete(uri, null, null) == 1) {
36059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood                return MTP_RESPONSE_OK;
36159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            } else {
36259c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood                return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
36359c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            }
364d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        } catch (RemoteException e) {
365d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood            Log.e(TAG, "RemoteException in deleteFile", e);
36659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood            return MTP_RESPONSE_GENERAL_ERROR;
367d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood        }
368d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    }
369d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
3709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    private int[] getObjectReferences(int handle) {
3719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        Log.d(TAG, "getObjectReferences for: " + handle);
3729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        Uri uri = MtpObjects.getReferencesUri(mVolumeName, handle);
3739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        Cursor c = null;
3749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        try {
3759a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null);
3769a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            if (c == null) {
3779a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                return null;
3789a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            }
3799a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            int count = c.getCount();
3809a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            if (count > 0) {
3819a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                int[] result = new int[count];
3829a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                for (int i = 0; i < count; i++) {
3839a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    c.moveToNext();
3849a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                    result[i] = c.getInt(0);
3859a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                }
3869a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                return result;
3879a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            }
3889a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        } catch (RemoteException e) {
3899a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            Log.e(TAG, "RemoteException in getObjectList", e);
3909a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        } finally {
3919a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            if (c != null) {
3929a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                c.close();
3939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            }
3949a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        }
3959a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return null;
3969a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
3979a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
3989a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    private int setObjectReferences(int handle, int[] references) {
3999a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        Uri uri = MtpObjects.getReferencesUri(mVolumeName, handle);
4009a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        int count = references.length;
4019a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        ContentValues[] valuesList = new ContentValues[count];
4029a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        for (int i = 0; i < count; i++) {
4039a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            ContentValues values = new ContentValues();
4049a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            values.put(MtpObjects.ObjectColumns._ID, references[i]);
4059a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            valuesList[i] = values;
4069a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        }
4079a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        try {
4089a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            if (count == mMediaProvider.bulkInsert(uri, valuesList)) {
4099a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood                return MTP_RESPONSE_OK;
4109a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            }
4119a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        } catch (RemoteException e) {
4129a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood            Log.e(TAG, "RemoteException in setObjectReferences", e);
4139a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        }
4149a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood        return MTP_RESPONSE_GENERAL_ERROR;
4159a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood    }
4169a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood
417d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    // used by the JNI code
418d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private int mNativeContext;
419d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood
420d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private native final void native_setup();
421d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood    private native final void native_finalize();
422d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood}
423