MtpDatabase.java revision 2b5f9ad1eaf0d6daaca5cf3761434a09309902bb
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; 222837eefc5459427138c080d445bb491c75630163Mike Lockwoodimport android.content.Intent; 23d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.database.Cursor; 2459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodimport android.database.sqlite.SQLiteDatabase; 25d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.net.Uri; 262b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwoodimport android.os.Environment; 27d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.os.RemoteException; 289a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.MediaStore.Audio; 293b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwoodimport android.provider.MediaStore.Files; 30ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwoodimport android.provider.MediaStore.Images; 31ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwoodimport android.provider.MediaStore.MediaColumns; 322837eefc5459427138c080d445bb491c75630163Mike Lockwoodimport android.provider.Mtp; 33d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.util.Log; 34d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 355ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwoodimport java.io.File; 365ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/** 38d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * {@hide} 39d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */ 40d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic class MtpDatabase { 41d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 42d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String TAG = "MtpDatabase"; 43d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 442837eefc5459427138c080d445bb491c75630163Mike Lockwood private final Context mContext; 45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final IContentProvider mMediaProvider; 46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final String mVolumeName; 47d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final Uri mObjectsUri; 4801788562f26f213f63c14483fd3977e23b8314abMike Lockwood private final String mMediaStoragePath; 492b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood private final String mExternalStoragePath; 50d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 512837eefc5459427138c080d445bb491c75630163Mike Lockwood // true if the database has been modified in the current MTP session 522837eefc5459427138c080d445bb491c75630163Mike Lockwood private boolean mDatabaseModified; 532837eefc5459427138c080d445bb491c75630163Mike Lockwood 5459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // database for writable MTP device properties 5559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private SQLiteDatabase mDevicePropDb; 5659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; 5759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 58b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // FIXME - this should be passed in via the constructor 59b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private final int mStorageID = 0x00010001; 60b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 61d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] ID_PROJECTION = new String[] { 623b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 63d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 646a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood private static final String[] PATH_PROJECTION = new String[] { 655ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns._ID, // 0 665ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns.DATA, // 1 675ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood }; 68d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] PATH_SIZE_PROJECTION = new String[] { 693b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 703b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATA, // 1 713b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.SIZE, // 2 72d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 73d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] OBJECT_INFO_PROJECTION = new String[] { 743b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 753b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATA, // 1 763b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.FORMAT, // 2 773b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.PARENT, // 3 783b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.SIZE, // 4 793b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATE_MODIFIED, // 5 80d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 813b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood private static final String ID_WHERE = Files.FileColumns._ID + "=?"; 823b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?"; 83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " 843b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood + Files.FileColumns.FORMAT + "=?"; 85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 8659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" }; 8759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final String DEVICE_PROPERTY_WHERE = "code=?"; 8859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 89d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private final MediaScanner mMediaScanner; 90d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 91d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood static { 92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood System.loadLibrary("media_jni"); 93d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 9501788562f26f213f63c14483fd3977e23b8314abMike Lockwood public MtpDatabase(Context context, String volumeName, String storagePath) { 96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood native_setup(); 97d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 982837eefc5459427138c080d445bb491c75630163Mike Lockwood mContext = context; 99d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mMediaProvider = context.getContentResolver().acquireProvider("media"); 100d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mVolumeName = volumeName; 10101788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath = storagePath; 1022b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood mExternalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath(); 1038490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood mObjectsUri = Files.getMtpObjectsUri(volumeName); 104d815f79766984fce499e147ecbacc01914683f74Mike Lockwood mMediaScanner = new MediaScanner(context); 10559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood openDevicePropertiesDatabase(context); 106d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 107d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 108d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood @Override 109dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood protected void finalize() throws Throwable { 110dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood try { 111dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood native_finalize(); 112dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } finally { 113dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood super.finalize(); 114dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } 115d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 116d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 1172b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood private String externalToMediaPath(String path) { 1182b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood // convert external storage path to media path 1192b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood if (path != null && mMediaStoragePath != null 1202b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood && mExternalStoragePath != null 1212b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood && path.startsWith(mExternalStoragePath)) { 1222b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood path = mMediaStoragePath + path.substring(mExternalStoragePath.length()); 1232b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood } 1242b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood return path; 1252b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood } 1262b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood 12759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private void openDevicePropertiesDatabase(Context context) { 12859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null); 12959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood int version = mDevicePropDb.getVersion(); 13059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 13159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // initialize if necessary 13259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (version != DEVICE_PROPERTIES_DATABASE_VERSION) { 13359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.execSQL("CREATE TABLE properties (" + 13459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 13559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "code INTEGER UNIQUE ON CONFLICT REPLACE," + 13659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "value TEXT" + 13759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood ");"); 13859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);"); 13959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION); 14059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 14159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 14259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 143d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private int beginSendObject(String path, int format, int parent, 144d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int storage, long size, long modified) { 1452837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 146d815f79766984fce499e147ecbacc01914683f74Mike Lockwood ContentValues values = new ContentValues(); 1473b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATA, path); 1483b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.FORMAT, format); 1493b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.PARENT, parent); 150d815f79766984fce499e147ecbacc01914683f74Mike Lockwood // storage is ignored for now 1513b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.SIZE, size); 1523b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATE_MODIFIED, modified); 153d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 154d815f79766984fce499e147ecbacc01914683f74Mike Lockwood try { 155d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Uri uri = mMediaProvider.insert(mObjectsUri, values); 156d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (uri != null) { 157d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return Integer.parseInt(uri.getPathSegments().get(2)); 158d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 159d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 160d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 161d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } catch (RemoteException e) { 162d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 163d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 164d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 165d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 166d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 167d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private void endSendObject(String path, int handle, int format, boolean succeeded) { 168d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (succeeded) { 1699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // handle abstract playlists separately 1709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // they do not exist in the file system so don't use the media scanner here 1715367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood if (format == MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST) { 1729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // Strip Windows Media Player file extension 1739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (path.endsWith(".pla")) { 1749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood path = path.substring(0, path.length() - 4); 1759a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 1769a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 1779a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // extract name from path 1789a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood String name = path; 1799a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int lastSlash = name.lastIndexOf('/'); 1809a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (lastSlash >= 0) { 1819a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood name = name.substring(lastSlash + 1); 1829a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 1839a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 1849a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(1); 1859a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.DATA, path); 1869a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.NAME, name); 1879a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle); 1889a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 1899a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Uri uri = mMediaProvider.insert(Audio.Playlists.EXTERNAL_CONTENT_URI, values); 1909a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 1919a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in endSendObject", e); 1929a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 1939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } else { 194c37255d5d0fd9e0ec02b0d7cb5c4b235e200d367Mike Lockwood mMediaScanner.scanMtpFile(path, mVolumeName, handle, format); 1959a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 196d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 197d815f79766984fce499e147ecbacc01914683f74Mike Lockwood deleteFile(handle); 198d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 199d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 200d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 201d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int[] getObjectList(int storageID, int format, int parent) { 202d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // we can ignore storageID until we support multiple storages 203d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectList parent: " + parent); 204d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 205d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 206d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (format != 0) { 207d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 208d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_FORMAT_WHERE, 209d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood new String[] { Integer.toString(parent), Integer.toString(format) }, 210d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood null); 211d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } else { 212d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 213d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_WHERE, new String[] { Integer.toString(parent) }, null); 214d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 215d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c == null) { 216d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "null cursor"); 217d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 218d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 219d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int count = c.getCount(); 220d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (count > 0) { 221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int[] result = new int[count]; 222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood for (int i = 0; i < count; i++) { 223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.moveToNext(); 224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood result[i] = c.getInt(0); 225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 226d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "returning " + result); 227d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return result; 228d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 229d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 230d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 231d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 232d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 233d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 234d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 235d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 236d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 237d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 2397a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood private int getNumObjects(int storageID, int format, int parent) { 2407a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood // we can ignore storageID until we support multiple storages 2417a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Log.d(TAG, "getObjectList parent: " + parent); 2427a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Cursor c = null; 2437a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood try { 2447a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (format != 0) { 2457a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 2467a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood PARENT_FORMAT_WHERE, 2477a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood new String[] { Integer.toString(parent), Integer.toString(format) }, 2487a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood null); 2497a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } else { 2507a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 2517a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood PARENT_WHERE, new String[] { Integer.toString(parent) }, null); 2527a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2537a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 2547a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return c.getCount(); 2557a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2567a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } catch (RemoteException e) { 2577a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Log.e(TAG, "RemoteException in getNumObjects", e); 2587a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } finally { 2597a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 2607a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c.close(); 2617a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2627a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2637a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return -1; 2647a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2657a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood 2664b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedPlaybackFormats() { 2674b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return new int[] { 268e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood // allow transfering arbitrary files 269e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood MtpConstants.FORMAT_UNDEFINED, 27012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood 271792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ASSOCIATION, 27212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TEXT, 27312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_HTML, 27412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WAV, 27512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP3, 27612b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MPEG, 27712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_EXIF_JPEG, 27812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF_EP, 27912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_GIF, 28012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_JFIF, 28112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PNG, 28212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF, 28312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WMA, 28412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_OGG, 28512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_AAC, 28612b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP4_CONTAINER, 28712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP2, 28812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_3GP_CONTAINER, 289792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST, 29012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WPL_PLAYLIST, 29112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_M3U_PLAYLIST, 29212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PLS_PLAYLIST, 29312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_XML_DOCUMENT, 2944b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood }; 2954b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 2964b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 2974b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedCaptureFormats() { 2984b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood // no capture formats yet 2994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return null; 3004b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 3014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 302ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] FILE_PROPERTIES = { 303ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match beginning of AUDIO_PROPERTIES, VIDEO_PROPERTIES 304ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // and IMAGE_PROPERTIES below 3055367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 3065367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 307d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 3085367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 3095367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 310d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 3115367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 312d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 313d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_NAME, 314ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 315ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 316ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 317ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] AUDIO_PROPERTIES = { 318ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 319ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 320ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 321ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 322ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 323ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 324ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 325ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 326ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 327ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 328ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 329ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 330ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 331ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // audio specific properties 332ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 333ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 334ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_ARTIST, 335ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_TRACK, 336ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, 337ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 338ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_GENRE, 339ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_COMPOSER, 340ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 341ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 342ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] VIDEO_PROPERTIES = { 343ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 344ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 345ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 346ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 347ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 348ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 349ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 350ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 351ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 352ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 353ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 354ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 355ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 356ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // video specific properties 357ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 358ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 359ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 360ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 361ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 362ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 363ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] IMAGE_PROPERTIES = { 364ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 365ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 366ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 367ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 368ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 369ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 370ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 371ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 372ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 373ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 374ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 375ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 376ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 377ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // image specific properties 378ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 379ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 380ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 381ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private int[] getSupportedObjectProperties(int format) { 382ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood switch (format) { 383ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MP3: 384ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WAV: 385ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMA: 386ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_OGG: 387ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_AAC: 388ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return AUDIO_PROPERTIES; 389ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MPEG: 390ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_3GP_CONTAINER: 391ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMV: 392ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return VIDEO_PROPERTIES; 393ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_EXIF_JPEG: 394ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_GIF: 395ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_PNG: 396ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_BMP: 397ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return IMAGE_PROPERTIES; 398ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood default: 399ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return FILE_PROPERTIES; 400ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 4014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 4024b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 4034b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedDeviceProperties() { 40459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return new int[] { 40559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, 40659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, 40759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood }; 4084b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 4094b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 410ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private String queryString(int id, String column) { 411ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood Cursor c = null; 412ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood try { 413ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // for now we are only reading properties from the "objects" table 414ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c = mMediaProvider.query(mObjectsUri, 415ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood new String [] { Files.FileColumns._ID, column }, 416ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood ID_WHERE, new String[] { Integer.toString(id) }, null); 417ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null && c.moveToNext()) { 418ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return c.getString(1); 419ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 420ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return ""; 421ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 422ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } catch (Exception e) { 423ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return null; 424ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } finally { 425ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null) { 426ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c.close(); 427ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 428ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 429ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 430ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 431ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private String queryGenre(int id) { 432ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood Cursor c = null; 433ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood try { 434ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id); 435ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c = mMediaProvider.query(uri, 436ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME }, 437ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood null, null, null); 438ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null && c.moveToNext()) { 439ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return c.getString(1); 440ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 441ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return ""; 442ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 443ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } catch (Exception e) { 444ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood Log.e(TAG, "queryGenre exception", e); 445ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return null; 446ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } finally { 447ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null) { 448ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c.close(); 449ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 450ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 451ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 452ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 453ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private boolean queryInt(int id, String column, long[] outValue) { 454ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood Cursor c = null; 455ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood try { 456ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // for now we are only reading properties from the "objects" table 457ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c = mMediaProvider.query(mObjectsUri, 458ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood new String [] { Files.FileColumns._ID, column }, 459ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood ID_WHERE, new String[] { Integer.toString(id) }, null); 460ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null && c.moveToNext()) { 461ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outValue[0] = c.getLong(1); 462ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return true; 463ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 464ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return false; 465ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } catch (Exception e) { 466ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return false; 467ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } finally { 468ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (c != null) { 469ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood c.close(); 470ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 471ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 472ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 473ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 474ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private String nameFromPath(String path) { 475ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // extract name from full path 476ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood int start = 0; 477ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood int lastSlash = path.lastIndexOf('/'); 478ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (lastSlash >= 0) { 479ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood start = lastSlash + 1; 480ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 481ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood int end = path.length(); 482ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (end - start > 255) { 483ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood end = start + 255; 484ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 485ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return path.substring(start, end); 486ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 487ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 4885ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood private int renameFile(int handle, String newName) { 4895ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Cursor c = null; 4905ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 4915ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood // first compute current path 4925ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood String path = null; 4935ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood String[] whereArgs = new String[] { Integer.toString(handle) }; 4945ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood try { 4956a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null); 4965ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood if (c != null && c.moveToNext()) { 4972b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood path = externalToMediaPath(c.getString(1)); 4985ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 4995ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } catch (RemoteException e) { 5005ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 5015ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 5025ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } finally { 5035ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood if (c != null) { 5045ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood c.close(); 5055ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5065ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5075ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood if (path == null) { 5085ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 5095ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5105ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 5115ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood // now rename the file. make sure this succeeds before updating database 5125ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood File oldFile = new File(path); 5135ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood int lastSlash = path.lastIndexOf('/'); 5145ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood if (lastSlash <= 1) { 5155ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 5165ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5175ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood String newPath = path.substring(0, lastSlash + 1) + newName; 5185ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood File newFile = new File(newPath); 5195ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood boolean success = oldFile.renameTo(newFile); 5205ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Log.d(TAG, "renaming "+ path + " to " + newPath + (success ? " succeeded" : " failed")); 5215ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood if (!success) { 5225ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 5235ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5245ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 5255ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood // finally update database 5265ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood ContentValues values = new ContentValues(); 5275ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood values.put(Files.FileColumns.DATA, newPath); 5285ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood int updated = 0; 5295ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood try { 5306a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood // note - we are relying on a special case in MediaProvider.update() to update 5316a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood // the paths for all children in the case where this is a directory. 5325ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); 5335ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } catch (RemoteException e) { 5345ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Log.e(TAG, "RemoteException in mMediaProvider.update", e); 5355ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5366a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood if (updated == 0) { 5375ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Log.e(TAG, "Unable to update path for " + path + " to " + newPath); 5385ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood // this shouldn't happen, but if it does we need to rename the file to its original name 5395ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood newFile.renameTo(oldFile); 5405ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 5415ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5425ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 5435ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_OK; 5445ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 5455ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 546d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int getObjectProperty(int handle, int property, 547d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood long[] outIntValue, char[] outStringValue) { 548d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectProperty: " + property); 549b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood String column = null; 550b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood boolean isString = false; 551b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 552b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood switch (property) { 5535367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_STORAGE_ID: 554b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outIntValue[0] = mStorageID; 5555367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 5565367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_OBJECT_FORMAT: 5573b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood column = Files.FileColumns.FORMAT; 558b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 5595367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_PROTECTION_STATUS: 560828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood // protection status is always 0 561828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood outIntValue[0] = 0; 5625367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 5635367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_OBJECT_SIZE: 5643b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood column = Files.FileColumns.SIZE; 565b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 5665367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_OBJECT_FILE_NAME: 567ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // special case - need to extract file name from full path 568ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood String value = queryString(handle, Files.FileColumns.DATA); 569ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (value != null) { 570ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood value = nameFromPath(value); 571ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood value.getChars(0, value.length(), outStringValue, 0); 572ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outStringValue[value.length()] = 0; 573ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_OK; 574ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 575ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 576ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 577ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_NAME: 578ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // first try title 579ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood String name = queryString(handle, MediaColumns.TITLE); 580ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // then try name 581ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (name == null) { 582ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood name = queryString(handle, Audio.PlaylistsColumns.NAME); 583ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 584ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // if title and name fail, extract name from full path 585ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (name == null) { 586ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood name = queryString(handle, Files.FileColumns.DATA); 587ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (name != null) { 588ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood name = nameFromPath(name); 589ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 590ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 591ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (name != null) { 592ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood name.getChars(0, name.length(), outStringValue, 0); 593ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outStringValue[name.length()] = 0; 594ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_OK; 595ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 596ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 597ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 5985367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_DATE_MODIFIED: 5993b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood column = Files.FileColumns.DATE_MODIFIED; 600b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 601ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_DATE_ADDED: 602ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Files.FileColumns.DATE_ADDED; 603ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 604ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE: 605ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.YEAR; 606ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 6075367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_PARENT_OBJECT: 6083b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood column = Files.FileColumns.PARENT; 609b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood break; 6105367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood case MtpConstants.PROPERTY_PERSISTENT_UID: 611828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood // PUID is concatenation of storageID and object handle 612828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood long puid = mStorageID; 613828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood puid <<= 32; 614828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood puid += handle; 615828d19dd96b05fa99abdc517701e5366543c324fMike Lockwood outIntValue[0] = puid; 6165367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 617ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_DURATION: 618ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.DURATION; 619ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 620ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_TRACK: 621ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (queryInt(handle, Audio.AudioColumns.TRACK, outIntValue)) { 622ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // track is stored in lower 3 decimal digits 623ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outIntValue[0] %= 1000; 624ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_OK; 625ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 626ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 627ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 628ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_DISPLAY_NAME: 629ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = MediaColumns.DISPLAY_NAME; 630ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 631ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 632ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_ARTIST: 633ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.ARTIST; 634ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 635ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 636ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_ALBUM_NAME: 637ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.ALBUM; 638ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 639ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 640ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_ALBUM_ARTIST: 641ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.ALBUM_ARTIST; 642ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 643ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 644ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_GENRE: 645ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood String genre = queryGenre(handle); 646ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (genre != null) { 647ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood genre.getChars(0, genre.length(), outStringValue, 0); 648ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outStringValue[genre.length()] = 0; 649ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_OK; 650ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 651ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 652ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 653ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_COMPOSER: 654ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Audio.AudioColumns.COMPOSER; 655ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 656ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 657ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.PROPERTY_DESCRIPTION: 658ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood column = Images.ImageColumns.DESCRIPTION; 659ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood isString = true; 660ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood break; 661b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood default: 6625367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 663b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 664b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 665ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (isString) { 666ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood String value = queryString(handle, column); 667ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (value != null) { 668ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood value.getChars(0, value.length(), outStringValue, 0); 669ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood outStringValue[value.length()] = 0; 6705367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 671b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 672ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } else { 673ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood if (queryInt(handle, column, outIntValue)) { 674ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return MtpConstants.RESPONSE_OK; 675b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 676b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 677b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // query failed if we get here 6785367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 679d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 680d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 68159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setObjectProperty(int handle, int property, 68259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood long intValue, String stringValue) { 68359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "setObjectProperty: " + property); 6845ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 6855ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood switch (property) { 6865ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood case MtpConstants.PROPERTY_OBJECT_FILE_NAME: 6875ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return renameFile(handle, stringValue); 6885ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 6895ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood default: 6905ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 6915ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 69259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 69359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 69459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { 69559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "getDeviceProperty: " + property); 69659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 69759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 69859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 69959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 70059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // writable string properties kept in our device property database 70159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Cursor c = null; 70259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood try { 70359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION, 70459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood DEVICE_PROPERTY_WHERE, new String[] { Integer.toString(property) }, 70559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood null, null, null); 70659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 70759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (c != null && c.moveToNext()) { 70859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood String value = c.getString(1); 70959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood int length = value.length(); 71059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (length > 255) { 71159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood length = 255; 71259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 71359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood value.getChars(0, length, outStringValue, 0); 71459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood outStringValue[length] = 0; 71559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } else { 71659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood outStringValue[0] = 0; 71759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 71859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_OK; 71959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } finally { 72059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (c != null) { 72159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood c.close(); 72259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 72359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 72459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 72559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 72659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 72759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 72859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 72959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setDeviceProperty(int property, long intValue, String stringValue) { 73059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "setDeviceProperty: " + property + " : " + stringValue); 73159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 73259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 73359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 73459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 73559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // writable string properties kept in our device property database 73659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood try { 73759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood ContentValues values = new ContentValues(); 73859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood values.put("code", property); 73959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood values.put("value", stringValue); 74059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.insert("properties", "code", values); 74159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_OK; 74259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } catch (Exception e) { 74359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 74459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 74559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 74659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 74759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 74859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 74959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 750d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private boolean getObjectInfo(int handle, int[] outStorageFormatParent, 751d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood char[] outName, long[] outSizeModified) { 752d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectInfo: " + handle); 753d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 754d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 755d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION, 756d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 757d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 758b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outStorageFormatParent[0] = mStorageID; 759d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[1] = c.getInt(2); 760d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[2] = c.getInt(3); 761d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 762d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // extract name from path 763d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood String path = c.getString(1); 764d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int lastSlash = path.lastIndexOf('/'); 765d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int start = (lastSlash >= 0 ? lastSlash + 1 : 0); 766d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int end = path.length(); 767d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (end - start > 255) { 768d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood end = start + 255; 769d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 770d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(start, end, outName, 0); 771d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outName[end - start] = 0; 772d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 773d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[0] = c.getLong(4); 774d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[1] = c.getLong(5); 775d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return true; 776d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 777d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 7782b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood Log.e(TAG, "RemoteException in getObjectInfo", e); 779d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 780d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 781d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 782d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 783d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 784d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return false; 785d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 786d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 78759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLength) { 788d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectFilePath: " + handle); 78901788562f26f213f63c14483fd3977e23b8314abMike Lockwood if (handle == 0) { 79001788562f26f213f63c14483fd3977e23b8314abMike Lockwood // special case root directory 79101788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath.getChars(0, mMediaStoragePath.length(), outFilePath, 0); 79201788562f26f213f63c14483fd3977e23b8314abMike Lockwood outFilePath[mMediaStoragePath.length()] = 0; 79301788562f26f213f63c14483fd3977e23b8314abMike Lockwood outFileLength[0] = 0; 79401788562f26f213f63c14483fd3977e23b8314abMike Lockwood return MtpConstants.RESPONSE_OK; 79501788562f26f213f63c14483fd3977e23b8314abMike Lockwood } 796d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 797d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 798d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_SIZE_PROJECTION, 799d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 800d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 8012b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood String path = externalToMediaPath(c.getString(1)); 802d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(0, path.length(), outFilePath, 0); 803d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFilePath[path.length()] = 0; 804d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFileLength[0] = c.getLong(2); 8055367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 80659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 8075367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 808d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 809d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 810d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 8115367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 812d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 813d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 814d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 815d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 816d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 817d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 818d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 819ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood private int deleteRecursive(int handle) throws RemoteException { 820ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood int[] children = getObjectList(0 /* storageID */, 0 /* format */, handle); 821ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood Uri uri = Files.getMtpObjectsUri(mVolumeName, handle); 822ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood // delete parent first, to avoid potential infinite recursion 823ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood int count = mMediaProvider.delete(uri, null, null); 824ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood if (count == 1) { 825ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood if (children != null) { 826ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood for (int i = 0; i < children.length; i++) { 827ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood count += deleteRecursive(children[i]); 828ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood } 829ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood } 830ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood } 831ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood return count; 832ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood } 833ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood 83459c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int deleteFile(int handle) { 835d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "deleteFile: " + handle); 8362837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 837d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 838ccb6e961941c607208ed9ac44db2dc9a9649b218Mike Lockwood if (deleteRecursive(handle) > 0) { 8395367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 84059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 8415367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 84259c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } 843d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 844d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in deleteFile", e); 8455367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 846d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 847d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 848d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 8499a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int[] getObjectReferences(int handle) { 8509a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.d(TAG, "getObjectReferences for: " + handle); 8518490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 8529a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Cursor c = null; 8539a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 8549a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null); 8559a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c == null) { 8569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 8579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8589a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = c.getCount(); 8599a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (count > 0) { 8609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int[] result = new int[count]; 8619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 8629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.moveToNext(); 8639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood result[i] = c.getInt(0); 8649a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return result; 8669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 8689a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 8699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } finally { 8709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c != null) { 8719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.close(); 8729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 8759a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8769a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 8779a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int setObjectReferences(int handle, int[] references) { 8782837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 8798490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 8809a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = references.length; 8819a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues[] valuesList = new ContentValues[count]; 8829a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 8839a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(); 8843b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns._ID, references[i]); 8859a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood valuesList[i] = values; 8869a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8879a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 8889a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (count == mMediaProvider.bulkInsert(uri, valuesList)) { 8895367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 8909a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8919a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 8929a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in setObjectReferences", e); 8939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8945367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 8959a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8969a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 8972837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionStarted() { 8982837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sessionStarted"); 8992837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 9002837eefc5459427138c080d445bb491c75630163Mike Lockwood } 9012837eefc5459427138c080d445bb491c75630163Mike Lockwood 9022837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionEnded() { 9032837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sessionEnded"); 9042837eefc5459427138c080d445bb491c75630163Mike Lockwood if (mDatabaseModified) { 9052837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sending ACTION_MTP_SESSION_END"); 9062837eefc5459427138c080d445bb491c75630163Mike Lockwood mContext.sendBroadcast(new Intent(Mtp.ACTION_MTP_SESSION_END)); 9072837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 9082837eefc5459427138c080d445bb491c75630163Mike Lockwood } 9092837eefc5459427138c080d445bb491c75630163Mike Lockwood } 9102837eefc5459427138c080d445bb491c75630163Mike Lockwood 911d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // used by the JNI code 912d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int mNativeContext; 913d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 914d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_setup(); 915d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_finalize(); 916d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood} 917