MtpDatabase.java revision 8ed67acf38ccdfdb89553ed58620a135f2100e10
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 170cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodpackage android.mtp; 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; 250cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodimport android.media.MediaScanner; 26d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.net.Uri; 272b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwoodimport android.os.Environment; 28d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.os.RemoteException; 29a31560598af25d5116effc2a6af0d9be12a0628dMike Lockwoodimport android.provider.MediaStore; 309a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.MediaStore.Audio; 313b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwoodimport android.provider.MediaStore.Files; 32ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwoodimport android.provider.MediaStore.Images; 33ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwoodimport android.provider.MediaStore.MediaColumns; 34d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.util.Log; 35ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwoodimport android.view.Display; 36ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwoodimport android.view.WindowManager; 37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 385ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwoodimport java.io.File; 397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport java.util.HashMap; 405ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 41d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/** 42d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * {@hide} 43d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */ 44d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic class MtpDatabase { 45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String TAG = "MtpDatabase"; 47d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 482837eefc5459427138c080d445bb491c75630163Mike Lockwood private final Context mContext; 49d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final IContentProvider mMediaProvider; 50d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final String mVolumeName; 51d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final Uri mObjectsUri; 5201788562f26f213f63c14483fd3977e23b8314abMike Lockwood private final String mMediaStoragePath; 53d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // cached property groups for single properties 557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByProperty 567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood = new HashMap<Integer, MtpPropertyGroup>(); 577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // cached property groups for all properties for a given format 597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByFormat 607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood = new HashMap<Integer, MtpPropertyGroup>(); 617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 622837eefc5459427138c080d445bb491c75630163Mike Lockwood // true if the database has been modified in the current MTP session 632837eefc5459427138c080d445bb491c75630163Mike Lockwood private boolean mDatabaseModified; 642837eefc5459427138c080d445bb491c75630163Mike Lockwood 6559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // database for writable MTP device properties 6659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private SQLiteDatabase mDevicePropDb; 6759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; 6859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 69b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood // FIXME - this should be passed in via the constructor 70b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood private final int mStorageID = 0x00010001; 71b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood 72d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] ID_PROJECTION = new String[] { 733b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 74d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 756a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood private static final String[] PATH_PROJECTION = new String[] { 765ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns._ID, // 0 775ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns.DATA, // 1 785ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood }; 79365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood private static final String[] PATH_SIZE_FORMAT_PROJECTION = new String[] { 803b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 813b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATA, // 1 823b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.SIZE, // 2 83365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood Files.FileColumns.FORMAT, // 3 84d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] OBJECT_INFO_PROJECTION = new String[] { 863b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 873b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATA, // 1 883b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.FORMAT, // 2 893b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.PARENT, // 3 903b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.SIZE, // 4 913b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATE_MODIFIED, // 5 92d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 933b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood private static final String ID_WHERE = Files.FileColumns._ID + "=?"; 94bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood private static final String PATH_WHERE = Files.FileColumns.DATA + "=?"; 953b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?"; 96d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " 973b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood + Files.FileColumns.FORMAT + "=?"; 98d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 9959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final String[] DEVICE_PROPERTY_PROJECTION = new String[] { "_id", "value" }; 10059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final String DEVICE_PROPERTY_WHERE = "code=?"; 10159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 102d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private final MediaScanner mMediaScanner; 103d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 104d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood static { 105d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood System.loadLibrary("media_jni"); 106d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 107d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 10801788562f26f213f63c14483fd3977e23b8314abMike Lockwood public MtpDatabase(Context context, String volumeName, String storagePath) { 109d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood native_setup(); 110d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 1112837eefc5459427138c080d445bb491c75630163Mike Lockwood mContext = context; 112d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mMediaProvider = context.getContentResolver().acquireProvider("media"); 113d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mVolumeName = volumeName; 11401788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath = storagePath; 1158490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood mObjectsUri = Files.getMtpObjectsUri(volumeName); 116d815f79766984fce499e147ecbacc01914683f74Mike Lockwood mMediaScanner = new MediaScanner(context); 11759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood openDevicePropertiesDatabase(context); 118d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 119d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 120d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood @Override 121dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood protected void finalize() throws Throwable { 122dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood try { 123dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood native_finalize(); 124dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } finally { 125dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood super.finalize(); 126dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } 127d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 128d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 12959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private void openDevicePropertiesDatabase(Context context) { 13059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null); 13159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood int version = mDevicePropDb.getVersion(); 13259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 13359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // initialize if necessary 13459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (version != DEVICE_PROPERTIES_DATABASE_VERSION) { 13559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.execSQL("CREATE TABLE properties (" + 13659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 13759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "code INTEGER UNIQUE ON CONFLICT REPLACE," + 13859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood "value TEXT" + 13959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood ");"); 14059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.execSQL("CREATE INDEX property_index ON properties (code);"); 14159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.setVersion(DEVICE_PROPERTIES_DATABASE_VERSION); 14259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 14359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 14459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 145d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private int beginSendObject(String path, int format, int parent, 146d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int storage, long size, long modified) { 147bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood // first make sure the object does not exist 148bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (path != null) { 149bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Cursor c = null; 150bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood try { 151bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, PATH_WHERE, 152bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood new String[] { path }, null); 153bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (c != null && c.getCount() > 0) { 154bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Log.w(TAG, "file already exists in beginSendObject: " + path); 155bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood return -1; 156bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 157bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } catch (RemoteException e) { 158bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 159bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } finally { 160bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (c != null) { 161bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood c.close(); 162bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 163bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 164bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 165bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood 1662837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 167d815f79766984fce499e147ecbacc01914683f74Mike Lockwood ContentValues values = new ContentValues(); 1683b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATA, path); 1693b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.FORMAT, format); 1703b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.PARENT, parent); 171d815f79766984fce499e147ecbacc01914683f74Mike Lockwood // storage is ignored for now 1723b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.SIZE, size); 1733b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATE_MODIFIED, modified); 174d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 175d815f79766984fce499e147ecbacc01914683f74Mike Lockwood try { 176d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Uri uri = mMediaProvider.insert(mObjectsUri, values); 177d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (uri != null) { 178d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return Integer.parseInt(uri.getPathSegments().get(2)); 179d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 180d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 181d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 182d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } catch (RemoteException e) { 183d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 184d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 185d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 186d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 187d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 1887a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood private void endSendObject(String path, int handle, int format, boolean succeeded) { 189d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (succeeded) { 1909a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // handle abstract playlists separately 1919a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // they do not exist in the file system so don't use the media scanner here 1925367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood if (format == MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST) { 1939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // extract name from path 1949a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood String name = path; 1959a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int lastSlash = name.lastIndexOf('/'); 1969a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (lastSlash >= 0) { 1979a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood name = name.substring(lastSlash + 1); 1989a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 1998cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood // strip trailing ".pla" from the name 2008cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood if (name.endsWith(".pla")) { 2018cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood name = name.substring(0, name.length() - 4); 2028cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood } 2039a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 2049a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(1); 2059a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.DATA, path); 2069a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.NAME, name); 2070b58c19840c577c8d8fd8aa5315676d61b78ba0fMike Lockwood values.put(Files.FileColumns.FORMAT, format); 2088ed67acf38ccdfdb89553ed58620a135f2100e10Mike Lockwood values.put(Files.FileColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000); 2099a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle); 2109a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 2119a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Uri uri = mMediaProvider.insert(Audio.Playlists.EXTERNAL_CONTENT_URI, values); 2129a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 2139a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in endSendObject", e); 2149a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 2159a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } else { 216c37255d5d0fd9e0ec02b0d7cb5c4b235e200d367Mike Lockwood mMediaScanner.scanMtpFile(path, mVolumeName, handle, format); 2179a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 218d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 219d815f79766984fce499e147ecbacc01914683f74Mike Lockwood deleteFile(handle); 220d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 223d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int[] getObjectList(int storageID, int format, int parent) { 224d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // we can ignore storageID until we support multiple storages 225d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectList parent: " + parent); 226d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 227d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 228d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (format != 0) { 229d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 230d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_FORMAT_WHERE, 231d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood new String[] { Integer.toString(parent), Integer.toString(format) }, 232d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood null); 233d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } else { 234d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 235d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood PARENT_WHERE, new String[] { Integer.toString(parent) }, null); 236d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 237d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c == null) { 238d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "null cursor"); 239d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 240d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 241d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int count = c.getCount(); 242d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (count > 0) { 243d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int[] result = new int[count]; 244d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood for (int i = 0; i < count; i++) { 245d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.moveToNext(); 246d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood result[i] = c.getInt(0); 247d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 248d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "returning " + result); 249d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return result; 250d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 251d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 252d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 253d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 254d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 255d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 256d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 257d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 258d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 259d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 260d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 2617a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood private int getNumObjects(int storageID, int format, int parent) { 2627a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood // we can ignore storageID until we support multiple storages 2637a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Log.d(TAG, "getObjectList parent: " + parent); 2647a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Cursor c = null; 2657a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood try { 2667a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (format != 0) { 2677a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 2687a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood PARENT_FORMAT_WHERE, 2697a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood new String[] { Integer.toString(parent), Integer.toString(format) }, 2707a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood null); 2717a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } else { 2727a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, 2737a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood PARENT_WHERE, new String[] { Integer.toString(parent) }, null); 2747a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2757a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 2767a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return c.getCount(); 2777a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2787a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } catch (RemoteException e) { 2797a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Log.e(TAG, "RemoteException in getNumObjects", e); 2807a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } finally { 2817a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 2827a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c.close(); 2837a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2847a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2857a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return -1; 2867a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 2877a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood 2884b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedPlaybackFormats() { 2894b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return new int[] { 290e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood // allow transfering arbitrary files 291e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood MtpConstants.FORMAT_UNDEFINED, 29212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood 293792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ASSOCIATION, 29412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TEXT, 29512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_HTML, 29612b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WAV, 29712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP3, 29812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MPEG, 29912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_EXIF_JPEG, 30012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF_EP, 30112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_GIF, 30212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_JFIF, 30312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PNG, 30412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF, 30512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WMA, 30612b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_OGG, 30712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_AAC, 30812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP4_CONTAINER, 30912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP2, 31012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_3GP_CONTAINER, 311792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST, 31212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WPL_PLAYLIST, 31312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_M3U_PLAYLIST, 31412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PLS_PLAYLIST, 31512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_XML_DOCUMENT, 3164b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood }; 3174b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 3184b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 3194b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedCaptureFormats() { 3204b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood // no capture formats yet 3214b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return null; 3224b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 3234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 324ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] FILE_PROPERTIES = { 325ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match beginning of AUDIO_PROPERTIES, VIDEO_PROPERTIES 326ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // and IMAGE_PROPERTIES below 3275367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 3285367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 329d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 3305367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 3315367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 332d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 3335367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 334d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 335d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_NAME, 336ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 337ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 338ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 339ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] AUDIO_PROPERTIES = { 340ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 341ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 342ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 343ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 344ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 345ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 346ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 347ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 348ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 349ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 350ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 351ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 352ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 353ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // audio specific properties 354ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 355ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 356ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_ARTIST, 357ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_TRACK, 358ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, 359ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 360ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_GENRE, 361ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_COMPOSER, 362ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 363ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 364ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] VIDEO_PROPERTIES = { 365ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 366ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 367ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 368ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 369ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 370ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 371ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 372ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 373ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 374ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 375ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 376ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 377ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 378ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // video specific properties 379ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 380ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 381ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 382ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 383ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 384ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 385ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] IMAGE_PROPERTIES = { 386ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 387ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 388ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 389ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 390ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 391ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 392ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 393ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 394ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 395ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 396ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 397ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 398ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 399ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // image specific properties 400ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 401ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 402ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 4037d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood static final int[] ALL_PROPERTIES = { 4047d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // NOTE must match FILE_PROPERTIES above 4057d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 4067d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 4077d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 4087d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 4097d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 4107d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 4117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 4127d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 4137d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_NAME, 4147d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 4157d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 4167d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 4177d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // image specific properties 4187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 4197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 4207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // audio specific properties 4217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ARTIST, 4227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 4237d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_ARTIST, 4247d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_TRACK, 4257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, 4267d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DURATION, 4277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_GENRE, 4287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_COMPOSER, 4297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 4307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // video specific properties 4317d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ARTIST, 4327d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 4337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DURATION, 4347d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 4357d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 4367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // image specific properties 4377d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 4387d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood }; 4397d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 440ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private int[] getSupportedObjectProperties(int format) { 441ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood switch (format) { 442ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MP3: 443ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WAV: 444ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMA: 445ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_OGG: 446ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_AAC: 447ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return AUDIO_PROPERTIES; 448ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MPEG: 449ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_3GP_CONTAINER: 450ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMV: 451ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return VIDEO_PROPERTIES; 452ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_EXIF_JPEG: 453ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_GIF: 454ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_PNG: 455ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_BMP: 456ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return IMAGE_PROPERTIES; 4577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood case 0: 4587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood return ALL_PROPERTIES; 459ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood default: 460ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return FILE_PROPERTIES; 461ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 4624b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 4634b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 4644b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedDeviceProperties() { 46559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return new int[] { 46659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, 46759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, 468ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, 46959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood }; 4704b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 4714b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 472e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 4737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private MtpPropertyList getObjectPropertyList(long handle, int format, long property, 474e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int groupCode, int depth) { 475e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // FIXME - implement group support 476e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (groupCode != 0) { 477e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED); 4785ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 4795ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 4807d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpPropertyGroup propertyGroup; 4817d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (property == 0xFFFFFFFFL) { 4827d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = mPropertyGroupsByFormat.get(format); 4837d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (propertyGroup == null) { 4847d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood int[] propertyList = getSupportedObjectProperties(format); 4857d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mVolumeName, propertyList); 4867d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood mPropertyGroupsByFormat.put(new Integer(format), propertyGroup); 487e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 4887d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood } else { 4897d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = mPropertyGroupsByProperty.get(property); 4907d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (propertyGroup == null) { 4917d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood int[] propertyList = new int[] { (int)property }; 4927d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mVolumeName, propertyList); 4937d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood mPropertyGroupsByProperty.put(new Integer((int)property), propertyGroup); 494e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 495e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 4967d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 4977d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood return propertyGroup.getPropertyList((int)handle, format, depth, mStorageID); 498e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 499e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 500e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood private int renameFile(int handle, String newName) { 501e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Cursor c = null; 502e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 503e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // first compute current path 504e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String path = null; 505e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String[] whereArgs = new String[] { Integer.toString(handle) }; 506e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood try { 507e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null); 508e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (c != null && c.moveToNext()) { 5091c4e88d0b0a8deede0415183739478b5ebc12bfdMike Lockwood path = c.getString(1); 510e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 511e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } catch (RemoteException e) { 512e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 513e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 514e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } finally { 515e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (c != null) { 516e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood c.close(); 517b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 518b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 519e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (path == null) { 520e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 521e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 522e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 523e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // now rename the file. make sure this succeeds before updating database 524e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood File oldFile = new File(path); 525e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int lastSlash = path.lastIndexOf('/'); 526e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (lastSlash <= 1) { 527e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 528e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 529e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String newPath = path.substring(0, lastSlash + 1) + newName; 530e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood File newFile = new File(newPath); 531e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood boolean success = oldFile.renameTo(newFile); 532e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.d(TAG, "renaming "+ path + " to " + newPath + (success ? " succeeded" : " failed")); 533e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (!success) { 534e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 535e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 536e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 537e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // finally update database 538e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood ContentValues values = new ContentValues(); 539e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood values.put(Files.FileColumns.DATA, newPath); 540e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int updated = 0; 541e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood try { 542e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // note - we are relying on a special case in MediaProvider.update() to update 543e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // the paths for all children in the case where this is a directory. 544e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood updated = mMediaProvider.update(mObjectsUri, values, ID_WHERE, whereArgs); 545e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } catch (RemoteException e) { 546e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "RemoteException in mMediaProvider.update", e); 547e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 548e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (updated == 0) { 549e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "Unable to update path for " + path + " to " + newPath); 550e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // this shouldn't happen, but if it does we need to rename the file to its original name 551e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood newFile.renameTo(oldFile); 552e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 553e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 554e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 555e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_OK; 556d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 557d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 55859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setObjectProperty(int handle, int property, 55959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood long intValue, String stringValue) { 56059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "setObjectProperty: " + property); 5615ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 5625ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood switch (property) { 5635ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood case MtpConstants.PROPERTY_OBJECT_FILE_NAME: 5645ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return renameFile(handle, stringValue); 5655ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 5665ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood default: 5675ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 5685ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 56959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 57059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 57159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { 57259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "getDeviceProperty: " + property); 57359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 57459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 57559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 57659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 57759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // writable string properties kept in our device property database 57859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Cursor c = null; 57959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood try { 58059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood c = mDevicePropDb.query("properties", DEVICE_PROPERTY_PROJECTION, 58159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood DEVICE_PROPERTY_WHERE, new String[] { Integer.toString(property) }, 58259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood null, null, null); 58359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 58459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (c != null && c.moveToNext()) { 58559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood String value = c.getString(1); 58659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood int length = value.length(); 58759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (length > 255) { 58859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood length = 255; 58959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 59059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood value.getChars(0, length, outStringValue, 0); 59159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood outStringValue[length] = 0; 59259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } else { 59359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood outStringValue[0] = 0; 59459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 59559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_OK; 59659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } finally { 59759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood if (c != null) { 59859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood c.close(); 59959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 60059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 60159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 602ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood case MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE: 603ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood // use screen size as max image size 604ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood Display display = ((WindowManager)mContext.getSystemService( 605ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood Context.WINDOW_SERVICE)).getDefaultDisplay(); 606ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood int width = display.getWidth(); 607ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood int height = display.getHeight(); 608ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood String imageSize = Integer.toString(width) + "x" + Integer.toString(height); 609ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood imageSize.getChars(0, imageSize.length(), outStringValue, 0); 610ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood outStringValue[imageSize.length()] = 0; 611ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood return MtpConstants.RESPONSE_OK; 612ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood 613ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood default: 614ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 615ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood } 61659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 61759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 61859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setDeviceProperty(int property, long intValue, String stringValue) { 61959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood Log.d(TAG, "setDeviceProperty: " + property + " : " + stringValue); 62059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 62159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 62259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 62359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 62459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood // writable string properties kept in our device property database 62559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood try { 62659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood ContentValues values = new ContentValues(); 62759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood values.put("code", property); 62859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood values.put("value", stringValue); 62959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood mDevicePropDb.insert("properties", "code", values); 63059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_OK; 63159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } catch (Exception e) { 63259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 63359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 63459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 63559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 63659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 63759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 63859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 639d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private boolean getObjectInfo(int handle, int[] outStorageFormatParent, 640d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood char[] outName, long[] outSizeModified) { 641d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectInfo: " + handle); 642d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 643d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 644d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION, 645d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 646d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 647b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood outStorageFormatParent[0] = mStorageID; 648d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[1] = c.getInt(2); 649d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[2] = c.getInt(3); 650d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 651d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // extract name from path 652d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood String path = c.getString(1); 653d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int lastSlash = path.lastIndexOf('/'); 654d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int start = (lastSlash >= 0 ? lastSlash + 1 : 0); 655d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int end = path.length(); 656d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (end - start > 255) { 657d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood end = start + 255; 658d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 659d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(start, end, outName, 0); 660d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outName[end - start] = 0; 661d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 662d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[0] = c.getLong(4); 663d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outSizeModified[1] = c.getLong(5); 664d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return true; 665d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 666d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 6672b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood Log.e(TAG, "RemoteException in getObjectInfo", e); 668d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 669d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 670d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 671d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 672d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 673d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return false; 674d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 675d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 676365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLengthFormat) { 677d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "getObjectFilePath: " + handle); 67801788562f26f213f63c14483fd3977e23b8314abMike Lockwood if (handle == 0) { 67901788562f26f213f63c14483fd3977e23b8314abMike Lockwood // special case root directory 68001788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath.getChars(0, mMediaStoragePath.length(), outFilePath, 0); 68101788562f26f213f63c14483fd3977e23b8314abMike Lockwood outFilePath[mMediaStoragePath.length()] = 0; 682365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[0] = 0; 683365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[1] = MtpConstants.FORMAT_ASSOCIATION; 68401788562f26f213f63c14483fd3977e23b8314abMike Lockwood return MtpConstants.RESPONSE_OK; 68501788562f26f213f63c14483fd3977e23b8314abMike Lockwood } 686d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 687d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 688365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION, 689d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 690d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 6911c4e88d0b0a8deede0415183739478b5ebc12bfdMike Lockwood String path = c.getString(1); 692d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(0, path.length(), outFilePath, 0); 693d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFilePath[path.length()] = 0; 694365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[0] = c.getLong(2); 695365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[1] = c.getLong(3); 6965367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 69759c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 6985367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 699d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 700d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 701d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 7025367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 703d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 704d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 705d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 706d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 707d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 708d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 709d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 71059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int deleteFile(int handle) { 711d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.d(TAG, "deleteFile: " + handle); 7122837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 71355f808cff9913a00164120a422af6ca45db5072bMike Lockwood String path = null; 71455f808cff9913a00164120a422af6ca45db5072bMike Lockwood int format = 0; 71555f808cff9913a00164120a422af6ca45db5072bMike Lockwood 71655f808cff9913a00164120a422af6ca45db5072bMike Lockwood Cursor c = null; 717d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 71855f808cff9913a00164120a422af6ca45db5072bMike Lockwood c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION, 71955f808cff9913a00164120a422af6ca45db5072bMike Lockwood ID_WHERE, new String[] { Integer.toString(handle) }, null); 72055f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (c != null && c.moveToNext()) { 72155f808cff9913a00164120a422af6ca45db5072bMike Lockwood // don't convert to media path here, since we will be matching 72255f808cff9913a00164120a422af6ca45db5072bMike Lockwood // against paths in the database matching /data/media 72355f808cff9913a00164120a422af6ca45db5072bMike Lockwood path = c.getString(1); 72455f808cff9913a00164120a422af6ca45db5072bMike Lockwood format = c.getInt(3); 72555f808cff9913a00164120a422af6ca45db5072bMike Lockwood } else { 72655f808cff9913a00164120a422af6ca45db5072bMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 72755f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 72855f808cff9913a00164120a422af6ca45db5072bMike Lockwood 72955f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (path == null || format == 0) { 73055f808cff9913a00164120a422af6ca45db5072bMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 73155f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 73255f808cff9913a00164120a422af6ca45db5072bMike Lockwood 73355f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (format == MtpConstants.FORMAT_ASSOCIATION) { 73455f808cff9913a00164120a422af6ca45db5072bMike Lockwood // recursive case - delete all children first 73555f808cff9913a00164120a422af6ca45db5072bMike Lockwood Uri uri = Files.getMtpObjectsUri(mVolumeName); 73655f808cff9913a00164120a422af6ca45db5072bMike Lockwood int count = mMediaProvider.delete(uri, "_data LIKE ?", 73755f808cff9913a00164120a422af6ca45db5072bMike Lockwood new String[] { path + "/%"}); 73855f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 73955f808cff9913a00164120a422af6ca45db5072bMike Lockwood 74055f808cff9913a00164120a422af6ca45db5072bMike Lockwood Uri uri = Files.getMtpObjectsUri(mVolumeName, handle); 74155f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (mMediaProvider.delete(uri, null, null) > 0) { 7425367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 74359c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 7445367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 74559c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } 746d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 747d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in deleteFile", e); 7485367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 74955f808cff9913a00164120a422af6ca45db5072bMike Lockwood } finally { 75055f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (c != null) { 75155f808cff9913a00164120a422af6ca45db5072bMike Lockwood c.close(); 75255f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 753d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 754d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 755d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 7569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int[] getObjectReferences(int handle) { 7579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.d(TAG, "getObjectReferences for: " + handle); 7588490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 7599a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Cursor c = null; 7609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 7619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null); 7629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c == null) { 7639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 7649a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = c.getCount(); 7669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (count > 0) { 7679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int[] result = new int[count]; 7689a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 7699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.moveToNext(); 7709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood result[i] = c.getInt(0); 7719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return result; 7739a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 7759a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 7769a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } finally { 7779a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c != null) { 7789a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.close(); 7799a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7809a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7819a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 7829a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7839a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 7849a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int setObjectReferences(int handle, int[] references) { 7852837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 7868490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 7879a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = references.length; 7889a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues[] valuesList = new ContentValues[count]; 7899a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 7909a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(); 7913b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns._ID, references[i]); 7929a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood valuesList[i] = values; 7939a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7949a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 7957adfd1896c17d734440962c9f8dbe4aad48bcb49Mike Lockwood if (mMediaProvider.bulkInsert(uri, valuesList) > 0) { 7965367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 7979a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 7989a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 7999a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in setObjectReferences", e); 8009a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8015367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 8029a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 8039a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 8042837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionStarted() { 8052837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sessionStarted"); 8062837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 8072837eefc5459427138c080d445bb491c75630163Mike Lockwood } 8082837eefc5459427138c080d445bb491c75630163Mike Lockwood 8092837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionEnded() { 8102837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sessionEnded"); 8112837eefc5459427138c080d445bb491c75630163Mike Lockwood if (mDatabaseModified) { 8122837eefc5459427138c080d445bb491c75630163Mike Lockwood Log.d(TAG, "sending ACTION_MTP_SESSION_END"); 813a31560598af25d5116effc2a6af0d9be12a0628dMike Lockwood mContext.sendBroadcast(new Intent(MediaStore.ACTION_MTP_SESSION_END)); 8142837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 8152837eefc5459427138c080d445bb491c75630163Mike Lockwood } 8162837eefc5459427138c080d445bb491c75630163Mike Lockwood } 8172837eefc5459427138c080d445bb491c75630163Mike Lockwood 818d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // used by the JNI code 819d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private int mNativeContext; 820d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 821d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_setup(); 822d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_finalize(); 823d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood} 824