MtpDatabase.java revision 59c777a24a2c639dfd84b7bf17e430e6d3424866
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; 25d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.provider.MediaStore.MtpObjects; 26d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.util.Log; 27d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 28d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/** 29d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * {@hide} 30d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */ 31d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic class MtpDatabase { 32d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 33d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String TAG = "MtpDatabase"; 34d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 35d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final IContentProvider mMediaProvider; 36d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final String mVolumeName; 37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final Uri mObjectsUri; 38d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 39b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // FIXME - this should be passed in via the constructor 40b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private final int mStorageID = 0x00010001; 41b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 42d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] ID_PROJECTION = new String[] { 43d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns._ID, // 0 44d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] PATH_SIZE_PROJECTION = new String[] { 46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns._ID, // 0 47d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.DATA, // 1 48d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.SIZE, // 2 49d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 50d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] OBJECT_INFO_PROJECTION = new String[] { 51d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns._ID, // 0 52d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.DATA, // 1 53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.FORMAT, // 2 54d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.PARENT, // 3 55d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.SIZE, // 4 56d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood MtpObjects.ObjectColumns.DATE_MODIFIED, // 5 57d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 58d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String ID_WHERE = MtpObjects.ObjectColumns._ID + "=?"; 59d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String PATH_WHERE = MtpObjects.ObjectColumns.DATA + "=?"; 60d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String PARENT_WHERE = MtpObjects.ObjectColumns.PARENT + "=?"; 61d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " 62d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood + MtpObjects.ObjectColumns.FORMAT + "=?"; 63d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 64d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private final MediaScanner mMediaScanner; 65d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 66b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // MTP property codes 67b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_STORAGE_ID = 0xDC01; 68b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_OBJECT_FORMAT = 0xDC02; 69b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_OBJECT_SIZE = 0xDC04; 70b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_OBJECT_FILE_NAME = 0xDC07; 71b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_DATE_MODIFIED = 0xDC09; 72b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_PROPERTY_PARENT_OBJECT = 0xDC0B; 73b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 74b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // MTP response codes 75b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_RESPONSE_OK = 0x2001; 76b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_RESPONSE_GENERAL_ERROR = 0x2002; 77b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_RESPONSE_INVALID_OBJECT_HANDLE = 0x2009; 78b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private static final int MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED = 0xA80A; 79b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 80d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood static { 81d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood System.loadLibrary("media_jni"); 82d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 84d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood public MtpDatabase(Context context, String volumeName) { 85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood native_setup(); 86d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 87d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mMediaProvider = context.getContentResolver().acquireProvider("media"); 88d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mVolumeName = volumeName; 89d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mObjectsUri = MtpObjects.getContentUri(volumeName); 90d815f79766984fce499e147ecbacc01914683f74Mike Lockwood mMediaScanner = new MediaScanner(context); 91d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 93d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood @Override 94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood protected void finalize() { 95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood native_finalize(); 96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 97d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 98d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private int beginSendObject(String path, int format, int parent, 99d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int storage, long size, long modified) { 100d815f79766984fce499e147ecbacc01914683f74Mike Lockwood ContentValues values = new ContentValues(); 101d815f79766984fce499e147ecbacc01914683f74Mike Lockwood values.put(MtpObjects.ObjectColumns.DATA, path); 102d815f79766984fce499e147ecbacc01914683f74Mike Lockwood values.put(MtpObjects.ObjectColumns.FORMAT, format); 103d815f79766984fce499e147ecbacc01914683f74Mike Lockwood values.put(MtpObjects.ObjectColumns.PARENT, parent); 104d815f79766984fce499e147ecbacc01914683f74Mike Lockwood // storage is ignored for now 105d815f79766984fce499e147ecbacc01914683f74Mike Lockwood values.put(MtpObjects.ObjectColumns.SIZE, size); 106d815f79766984fce499e147ecbacc01914683f74Mike Lockwood values.put(MtpObjects.ObjectColumns.DATE_MODIFIED, modified); 107d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 108d815f79766984fce499e147ecbacc01914683f74Mike Lockwood try { 109d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Uri uri = mMediaProvider.insert(mObjectsUri, values); 110d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (uri != null) { 111d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return Integer.parseInt(uri.getPathSegments().get(2)); 112d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 113d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 114d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 115d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } catch (RemoteException e) { 116d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 117d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 118d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 119d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 120d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 121d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private void endSendObject(String path, int handle, int format, boolean succeeded) { 122d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (succeeded) { 123d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Uri uri = mMediaScanner.scanMtpFile(path, mVolumeName, handle, format); 124d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 125d815f79766984fce499e147ecbacc01914683f74Mike Lockwood deleteFile(handle); 126d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 127d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 128d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 129d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int[] getObjectList(int storageID, int format, int parent) { 130d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // we can ignore storageID until we support multiple storages 131d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectList parent: " + parent); 132d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 133d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 134d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (format != 0) { 135d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 136d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_FORMAT_WHERE, 137d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood new String[] { Integer.toString(parent), Integer.toString(format) }, 138d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood null); 139d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } else { 140d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 141d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_WHERE, new String[] { Integer.toString(parent) }, null); 142d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 143d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c == null) { 144d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "null cursor"); 145d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 146d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 147d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int count = c.getCount(); 148d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (count > 0) { 149d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int[] result = new int[count]; 150d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood for (int i = 0; i < count; i++) { 151d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.moveToNext(); 152d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood result[i] = c.getInt(0); 153d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 154d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "returning " + result); 155d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return result; 156d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 157d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 158d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 159d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 160d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 161d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 162d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 163d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 164d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 165d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 166d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 167d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int getObjectProperty(int handle, int property, 168d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood long[] outIntValue, char[] outStringValue) { 169d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectProperty: " + property); 170b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood String column = null; 171b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood boolean isString = false; 172b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 173b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood switch (property) { 174b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_STORAGE_ID: 175b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outIntValue[0] = mStorageID; 176b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood return MTP_RESPONSE_OK; 177b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_OBJECT_FORMAT: 178b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood column = MtpObjects.ObjectColumns.FORMAT; 179b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 180b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_OBJECT_SIZE: 181b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood column = MtpObjects.ObjectColumns.SIZE; 182b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 183b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_OBJECT_FILE_NAME: 184b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood column = MtpObjects.ObjectColumns.DATA; 185b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood isString = true; 186b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 187b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_DATE_MODIFIED: 188b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood column = MtpObjects.ObjectColumns.DATE_MODIFIED; 189b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 190b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood case MTP_PROPERTY_PARENT_OBJECT: 191b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood column = MtpObjects.ObjectColumns.PARENT; 192b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 193b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood default: 194b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 195b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 196b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 197b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood Cursor c = null; 198b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood try { 199b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // for now we are only reading properties from the "objects" table 200b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood c = mMediaProvider.query(mObjectsUri, 201b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood new String [] { MtpObjects.ObjectColumns._ID, column }, 202b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 203b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (c != null && c.moveToNext()) { 204b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (isString) { 205b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood String value = c.getString(1); 206b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood int start = 0; 207b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 208b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (property == MTP_PROPERTY_OBJECT_FILE_NAME) { 209b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // extract name from full path 210b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood int lastSlash = value.lastIndexOf('/'); 211b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (lastSlash >= 0) { 212b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood start = lastSlash + 1; 213b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 214b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 215b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood int end = value.length(); 216b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (end - start > 255) { 217b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood end = start + 255; 218b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 219b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood value.getChars(start, end, outStringValue, 0); 220b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outStringValue[end - start] = 0; 221b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } else { 222b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outIntValue[0] = c.getLong(1); 223b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 224b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood return MTP_RESPONSE_OK; 225b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 226b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } catch (Exception e) { 227b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 228b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } finally { 229b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood if (c != null) { 230b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood c.close(); 231b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 232b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 233b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // query failed if we get here 234b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood return MTP_RESPONSE_INVALID_OBJECT_HANDLE; 235d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 236d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 237d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private boolean getObjectInfo(int handle, int[] outStorageFormatParent, 238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood char[] outName, long[] outSizeModified) { 239d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectInfo: " + handle); 240d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 241d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 242d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION, 243d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 244d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 245b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outStorageFormatParent[0] = mStorageID; 246d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[1] = c.getInt(2); 247d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[2] = c.getInt(3); 248d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 249d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // extract name from path 250d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood String path = c.getString(1); 251d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int lastSlash = path.lastIndexOf('/'); 252d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int start = (lastSlash >= 0 ? lastSlash + 1 : 0); 253d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int end = path.length(); 254d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (end - start > 255) { 255d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood end = start + 255; 256d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 257d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(start, end, outName, 0); 258d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outName[end - start] = 0; 259d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 260d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[0] = c.getLong(4); 261d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[1] = c.getLong(5); 262d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return true; 263d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 264d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 265d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectProperty", e); 266d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 267d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 268d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 269d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 270d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 271d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return false; 272d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 273d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 27459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLength) { 275d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectFilePath: " + handle); 276d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 277d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 278d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_SIZE_PROJECTION, 279d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 280d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 281d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood String path = c.getString(1); 282d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(0, path.length(), outFilePath, 0); 283d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFilePath[path.length()] = 0; 284d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFileLength[0] = c.getLong(2); 28559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_OK; 28659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 28759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_INVALID_OBJECT_HANDLE; 288d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 289d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 290d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 29159c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 292d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 293d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 294d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 295d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 296d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 297d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 298d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 29959c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int deleteFile(int handle) { 300d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "deleteFile: " + handle); 301d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Uri uri = MtpObjects.getContentUri(mVolumeName, handle); 302d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 30359c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood if (mMediaProvider.delete(uri, null, null) == 1) { 30459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_OK; 30559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 30659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_INVALID_OBJECT_HANDLE; 30759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } 308d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 309d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in deleteFile", e); 31059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood return MTP_RESPONSE_GENERAL_ERROR; 311d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 312d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 313d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 314d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // used by the JNI code 315d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int mNativeContext; 316d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 317d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_setup(); 318d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_finalize(); 319d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood} 320