MtpDatabase.java revision 56c85244b9be0fc6f6c2baf5f9a53f2364d5ec5e
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 1956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodimport android.content.BroadcastReceiver; 20d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.content.Context; 21d815f79766984fce499e147ecbacc01914683f74Mike Lockwoodimport android.content.ContentValues; 22d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.content.IContentProvider; 232837eefc5459427138c080d445bb491c75630163Mike Lockwoodimport android.content.Intent; 2456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodimport android.content.IntentFilter; 25775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwoodimport android.content.SharedPreferences; 26d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.database.Cursor; 2759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwoodimport android.database.sqlite.SQLiteDatabase; 280cd0136d440cf6ad9d5fab430269116786e671ecMike Lockwoodimport android.media.MediaScanner; 29d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.net.Uri; 3056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodimport android.os.BatteryManager; 3156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwoodimport android.os.BatteryStats; 32d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.os.RemoteException; 33a31560598af25d5116effc2a6af0d9be12a0628dMike Lockwoodimport android.provider.MediaStore; 349a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwoodimport android.provider.MediaStore.Audio; 353b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwoodimport android.provider.MediaStore.Files; 36ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwoodimport android.provider.MediaStore.MediaColumns; 37d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodimport android.util.Log; 38ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwoodimport android.view.Display; 39ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwoodimport android.view.WindowManager; 40d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 415ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwoodimport java.io.File; 427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwoodimport java.util.HashMap; 43fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.chaimport java.util.Locale; 445ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 45d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood/** 46d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood * {@hide} 47d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood */ 48d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwoodpublic class MtpDatabase { 49d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 50d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String TAG = "MtpDatabase"; 51d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 522837eefc5459427138c080d445bb491c75630163Mike Lockwood private final Context mContext; 5335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn private final String mPackageName; 54d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final IContentProvider mMediaProvider; 55d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final String mVolumeName; 56d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private final Uri mObjectsUri; 5773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // path to primary storage 5873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private final String mMediaStoragePath; 5973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // if not null, restrict all queries to these subdirectories 6073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private final String[] mSubDirectories; 6173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // where clause for restricting queries to files in mSubDirectories 6273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private String mSubDirectoriesWhere; 6373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // where arguments for restricting queries to files in mSubDirectories 6473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private String[] mSubDirectoriesWhereArgs; 6573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 66b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>(); 67d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // cached property groups for single properties 697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByProperty 707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood = new HashMap<Integer, MtpPropertyGroup>(); 717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 727d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // cached property groups for all properties for a given format 737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByFormat 747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood = new HashMap<Integer, MtpPropertyGroup>(); 757d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 762837eefc5459427138c080d445bb491c75630163Mike Lockwood // true if the database has been modified in the current MTP session 772837eefc5459427138c080d445bb491c75630163Mike Lockwood private boolean mDatabaseModified; 782837eefc5459427138c080d445bb491c75630163Mike Lockwood 79775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood // SharedPreferences for writable MTP device properties 80775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood private SharedPreferences mDeviceProperties; 8159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; 8259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 83d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] ID_PROJECTION = new String[] { 843b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 85d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 866a6a3aff17e057eeb1457ac4d04ab4b5e8f53abeMike Lockwood private static final String[] PATH_PROJECTION = new String[] { 875ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns._ID, // 0 885ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood Files.FileColumns.DATA, // 1 895ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood }; 90f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood private static final String[] PATH_FORMAT_PROJECTION = new String[] { 913b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 923b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.DATA, // 1 93f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood Files.FileColumns.FORMAT, // 2 94d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 95d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private static final String[] OBJECT_INFO_PROJECTION = new String[] { 963b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns._ID, // 0 97b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood Files.FileColumns.STORAGE_ID, // 1 983b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.FORMAT, // 2 993b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood Files.FileColumns.PARENT, // 3 100b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood Files.FileColumns.DATA, // 4 1011341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood Files.FileColumns.DATE_ADDED, // 5 1021341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood Files.FileColumns.DATE_MODIFIED, // 6 103d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood }; 1043b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood private static final String ID_WHERE = Files.FileColumns._ID + "=?"; 105bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood private static final String PATH_WHERE = Files.FileColumns.DATA + "=?"; 1066acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood 1076acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood private static final String STORAGE_WHERE = Files.FileColumns.STORAGE_ID + "=?"; 10858e6831ccb54b33a914115e88ebb67e720615fb8Mike Lockwood private static final String FORMAT_WHERE = Files.FileColumns.FORMAT + "=?"; 10958e6831ccb54b33a914115e88ebb67e720615fb8Mike Lockwood private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?"; 1106acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood private static final String STORAGE_FORMAT_WHERE = STORAGE_WHERE + " AND " 111b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood + Files.FileColumns.FORMAT + "=?"; 1126acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood private static final String STORAGE_PARENT_WHERE = STORAGE_WHERE + " AND " 1136acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood + Files.FileColumns.PARENT + "=?"; 1146acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood private static final String FORMAT_PARENT_WHERE = FORMAT_WHERE + " AND " 1156acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood + Files.FileColumns.PARENT + "=?"; 1166acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood private static final String STORAGE_FORMAT_PARENT_WHERE = STORAGE_FORMAT_WHERE + " AND " 1176acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood + Files.FileColumns.PARENT + "=?"; 118d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 119d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private final MediaScanner mMediaScanner; 12056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood private MtpServer mServer; 12156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood 12256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood // read from native code 12356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood private int mBatteryLevel; 12456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood private int mBatteryScale; 125d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 126d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood static { 127d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood System.loadLibrary("media_jni"); 128d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 129d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 13056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() { 13156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood @Override 13256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood public void onReceive(Context context, Intent intent) { 13356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood String action = intent.getAction(); 13456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { 13556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mBatteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); 13656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood int newLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); 13756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood if (newLevel != mBatteryLevel) { 13856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mBatteryLevel = newLevel; 13956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood if (mServer != null) { 14056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood // send device property changed event 14156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mServer.sendDevicePropertyChanged( 14256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL); 14356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 14456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 14556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 14656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 14756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood }; 14856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood 14973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood public MtpDatabase(Context context, String volumeName, String storagePath, 15073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String[] subDirectories) { 151d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood native_setup(); 152d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 1532837eefc5459427138c080d445bb491c75630163Mike Lockwood mContext = context; 15435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mPackageName = context.getPackageName(); 155d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mMediaProvider = context.getContentResolver().acquireProvider("media"); 156d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood mVolumeName = volumeName; 15701788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath = storagePath; 1588490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood mObjectsUri = Files.getMtpObjectsUri(volumeName); 159d815f79766984fce499e147ecbacc01914683f74Mike Lockwood mMediaScanner = new MediaScanner(context); 160fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha 16173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood mSubDirectories = subDirectories; 16273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (subDirectories != null) { 16373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // Compute "where" string for restricting queries to subdirectories 16473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood StringBuilder builder = new StringBuilder(); 16573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood builder.append("("); 16673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood int count = subDirectories.length; 16773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (int i = 0; i < count; i++) { 16873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood builder.append(Files.FileColumns.DATA + "=? OR " 16973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood + Files.FileColumns.DATA + " LIKE ?"); 17073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (i != count - 1) { 17173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood builder.append(" OR "); 17273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 17373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 17473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood builder.append(")"); 17573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood mSubDirectoriesWhere = builder.toString(); 17673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 17773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // Compute "where" arguments for restricting queries to subdirectories 17873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood mSubDirectoriesWhereArgs = new String[count * 2]; 17973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (int i = 0, j = 0; i < count; i++) { 18073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String path = subDirectories[i]; 18173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood mSubDirectoriesWhereArgs[j++] = path; 18273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood mSubDirectoriesWhereArgs[j++] = path + "/%"; 18373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 18473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 18573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 186fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha // Set locale to MediaScanner. 187fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha Locale locale = context.getResources().getConfiguration().locale; 188fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha if (locale != null) { 189fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha String language = locale.getLanguage(); 190fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha String country = locale.getCountry(); 191fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha if (language != null) { 192fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha if (country != null) { 193fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha mMediaScanner.setLocale(language + "_" + country); 194fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha } else { 195fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha mMediaScanner.setLocale(language); 196fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha } 197fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha } 198fe464a76d8fc858be971dbb5e67b1d22fd925347dujin.cha } 199775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood initDeviceProperties(context); 200d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 201d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 20256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood public void setServer(MtpServer server) { 20356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mServer = server; 20456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood 20556c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood // register for battery notifications when we are connected 20656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood if (server != null) { 20756c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mContext.registerReceiver(mBatteryReceiver, 20856c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 20956c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } else { 21056c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood mContext.unregisterReceiver(mBatteryReceiver); 21156c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 21256c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood } 21356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood 214d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood @Override 215dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood protected void finalize() throws Throwable { 216dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood try { 217dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood native_finalize(); 218dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } finally { 219dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood super.finalize(); 220dbead321daf2c16dc74e182bec591b278cfccb2cMike Lockwood } 221d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 222d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 223b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood public void addStorage(MtpStorage storage) { 224b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood mStorageMap.put(storage.getPath(), storage); 225b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } 226b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood 227b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood public void removeStorage(MtpStorage storage) { 228b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood mStorageMap.remove(storage.getPath()); 229b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } 230b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood 231775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood private void initDeviceProperties(Context context) { 232775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood final String devicePropertiesName = "device-properties"; 233775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood mDeviceProperties = context.getSharedPreferences(devicePropertiesName, Context.MODE_PRIVATE); 234775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood File databaseFile = context.getDatabasePath(devicePropertiesName); 235775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood 236775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (databaseFile.exists()) { 237775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood // for backward compatibility - read device properties from sqlite database 238775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood // and migrate them to shared prefs 239775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood SQLiteDatabase db = null; 240775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood Cursor c = null; 241775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood try { 242775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood db = context.openOrCreateDatabase("device-properties", Context.MODE_PRIVATE, null); 243775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (db != null) { 244775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood c = db.query("properties", new String[] { "_id", "code", "value" }, 245775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood null, null, null, null, null); 246775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (c != null) { 247775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood SharedPreferences.Editor e = mDeviceProperties.edit(); 248775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood while (c.moveToNext()) { 249775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood String name = c.getString(1); 250775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood String value = c.getString(2); 251775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood e.putString(name, value); 252775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } 253775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood e.commit(); 254775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } 255775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } 256775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } catch (Exception e) { 257775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood Log.e(TAG, "failed to migrate device properties", e); 258775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } finally { 259775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (c != null) c.close(); 260775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (db != null) db.close(); 261775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood } 2623ed02535fdc3c752346c40b57962905b7072e693jangwon.lee context.deleteDatabase(devicePropertiesName); 26359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 26459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 26559e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 26673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // check to see if the path is contained in one of our storage subdirectories 26773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // returns true if we have no special subdirectories 26873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private boolean inStorageSubDirectory(String path) { 26973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (mSubDirectories == null) return true; 27073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (path == null) return false; 27173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 27273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood boolean allowed = false; 27373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood int pathLength = path.length(); 27473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (int i = 0; i < mSubDirectories.length && !allowed; i++) { 27573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String subdir = mSubDirectories[i]; 27673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood int subdirLength = subdir.length(); 27773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (subdirLength < pathLength && 27873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood path.charAt(subdirLength) == '/' && 27973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood path.startsWith(subdir)) { 28073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood allowed = true; 28173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 28273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 28373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood return allowed; 28473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 28573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 28673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // check to see if the path matches one of our storage subdirectories 28773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // returns true if we have no special subdirectories 28873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood private boolean isStorageSubDirectory(String path) { 28973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (mSubDirectories == null) return false; 29073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (int i = 0; i < mSubDirectories.length; i++) { 29173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (path.equals(mSubDirectories[i])) { 29273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood return true; 29373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 29473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 29573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood return false; 29673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 29773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 298d815f79766984fce499e147ecbacc01914683f74Mike Lockwood private int beginSendObject(String path, int format, int parent, 299b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood int storageId, long size, long modified) { 30073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // if mSubDirectories is not null, do not allow copying files to any other locations 30173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (!inStorageSubDirectory(path)) return -1; 30273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 30373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // make sure the object does not exist 304bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (path != null) { 305bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Cursor c = null; 306bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood try { 30735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, mObjectsUri, ID_PROJECTION, PATH_WHERE, 30875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown new String[] { path }, null, null); 309bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (c != null && c.getCount() > 0) { 310bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Log.w(TAG, "file already exists in beginSendObject: " + path); 311bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood return -1; 312bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 313bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } catch (RemoteException e) { 314bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 315bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } finally { 316bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood if (c != null) { 317bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood c.close(); 318bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 319bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 320bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood } 321bafca214eaf326441e5157d645b2ee7fe8c7d1abMike Lockwood 3222837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 323d815f79766984fce499e147ecbacc01914683f74Mike Lockwood ContentValues values = new ContentValues(); 3243b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATA, path); 3253b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.FORMAT, format); 3263b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.PARENT, parent); 327b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood values.put(Files.FileColumns.STORAGE_ID, storageId); 3283b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.SIZE, size); 3293b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns.DATE_MODIFIED, modified); 330d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 331d815f79766984fce499e147ecbacc01914683f74Mike Lockwood try { 33235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Uri uri = mMediaProvider.insert(mPackageName, mObjectsUri, values); 333d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (uri != null) { 334d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return Integer.parseInt(uri.getPathSegments().get(2)); 335d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 336d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 337d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 338d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } catch (RemoteException e) { 339d815f79766984fce499e147ecbacc01914683f74Mike Lockwood Log.e(TAG, "RemoteException in beginSendObject", e); 340d815f79766984fce499e147ecbacc01914683f74Mike Lockwood return -1; 341d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 342d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 343d815f79766984fce499e147ecbacc01914683f74Mike Lockwood 3447a0bd17bceaf3efc3732e30c538fae420d3b742cMike Lockwood private void endSendObject(String path, int handle, int format, boolean succeeded) { 345d815f79766984fce499e147ecbacc01914683f74Mike Lockwood if (succeeded) { 3469a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // handle abstract playlists separately 3479a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // they do not exist in the file system so don't use the media scanner here 3485367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood if (format == MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST) { 3499a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood // extract name from path 3509a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood String name = path; 3519a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int lastSlash = name.lastIndexOf('/'); 3529a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (lastSlash >= 0) { 3539a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood name = name.substring(lastSlash + 1); 3549a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 3558cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood // strip trailing ".pla" from the name 3568cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood if (name.endsWith(".pla")) { 3578cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood name = name.substring(0, name.length() - 4); 3588cc6eb1e4c708fb4398292ba30aa80ad5770d7ceMike Lockwood } 3599a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 3609a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(1); 3619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.DATA, path); 3629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(Audio.Playlists.NAME, name); 3630b58c19840c577c8d8fd8aa5315676d61b78ba0fMike Lockwood values.put(Files.FileColumns.FORMAT, format); 3648ed67acf38ccdfdb89553ed58620a135f2100e10Mike Lockwood values.put(Files.FileColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000); 3659a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle); 3669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 36735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Uri uri = mMediaProvider.insert(mPackageName, 36835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Audio.Playlists.EXTERNAL_CONTENT_URI, values); 3699a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 3709a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in endSendObject", e); 3719a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 3729a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } else { 373c37255d5d0fd9e0ec02b0d7cb5c4b235e200d367Mike Lockwood mMediaScanner.scanMtpFile(path, mVolumeName, handle, format); 3749a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 375d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } else { 376d815f79766984fce499e147ecbacc01914683f74Mike Lockwood deleteFile(handle); 377d815f79766984fce499e147ecbacc01914683f74Mike Lockwood } 378d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 379d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 380b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood private Cursor createObjectQuery(int storageID, int format, int parent) throws RemoteException { 38173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String where; 38273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String[] whereArgs; 38373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 3846acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (storageID == 0xFFFFFFFF) { 3856acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all stores 3866acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (format == 0) { 3876acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all formats 3886acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (parent == 0) { 3896acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all objects 39073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = null; 39173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = null; 39273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } else { 39373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (parent == 0xFFFFFFFF) { 39473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // all objects in root of store 39573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood parent = 0; 39673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 39773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = PARENT_WHERE; 39873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(parent) }; 3996acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood } 400b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } else { 4016acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query specific format 4026acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (parent == 0) { 4036acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all objects 40473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = FORMAT_WHERE; 40573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(format) }; 40673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } else { 40773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (parent == 0xFFFFFFFF) { 40873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // all objects in root of store 40973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood parent = 0; 41073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 41173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = FORMAT_PARENT_WHERE; 41273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(format), 41373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood Integer.toString(parent) }; 4146acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood } 415b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } 416b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } else { 4176acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query specific store 4186acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (format == 0) { 4196acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all formats 4206acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (parent == 0) { 4216acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all objects 42273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = STORAGE_WHERE; 42373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(storageID) }; 42473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } else { 42573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (parent == 0xFFFFFFFF) { 42673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // all objects in root of store 42773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood parent = 0; 42873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 42973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = STORAGE_PARENT_WHERE; 43073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(storageID), 43173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood Integer.toString(parent) }; 4326acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood } 433d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } else { 4346acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query specific format 4356acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood if (parent == 0) { 4366acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood // query all objects 43773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = STORAGE_FORMAT_WHERE; 43873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(storageID), 43973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood Integer.toString(format) }; 44073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } else { 44173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (parent == 0xFFFFFFFF) { 44273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // all objects in root of store 44373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood parent = 0; 44473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 44573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = STORAGE_FORMAT_PARENT_WHERE; 44673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = new String[] { Integer.toString(storageID), 44773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood Integer.toString(format), 44873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood Integer.toString(parent) }; 4496acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood } 45073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 45173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 45273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 45373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // if we are restricting queries to mSubDirectories, we need to add the restriction 45473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // onto our "where" arguments 45573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (mSubDirectoriesWhere != null) { 45673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (where == null) { 45773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = mSubDirectoriesWhere; 45873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = mSubDirectoriesWhereArgs; 45973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } else { 46073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood where = where + " AND " + mSubDirectoriesWhere; 46173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 46273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // create new array to hold whereArgs and mSubDirectoriesWhereArgs 46373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood String[] newWhereArgs = 46473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood new String[whereArgs.length + mSubDirectoriesWhereArgs.length]; 46573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood int i, j; 46673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (i = 0; i < whereArgs.length; i++) { 46773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood newWhereArgs[i] = whereArgs[i]; 4686acc90fc216530f0a5bbf7339066af9b415cbb02Mike Lockwood } 46973e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood for (j = 0; j < mSubDirectoriesWhereArgs.length; i++, j++) { 47073e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood newWhereArgs[i] = mSubDirectoriesWhereArgs[j]; 47173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 47273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood whereArgs = newWhereArgs; 473d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 474b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } 47573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 47635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return mMediaProvider.query(mPackageName, mObjectsUri, ID_PROJECTION, where, 47735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn whereArgs, null, null); 478b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood } 479b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood 480b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood private int[] getObjectList(int storageID, int format, int parent) { 481b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood Cursor c = null; 482b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood try { 483b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood c = createObjectQuery(storageID, format, parent); 484d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c == null) { 485d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 486d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 487d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int count = c.getCount(); 488d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (count > 0) { 489d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int[] result = new int[count]; 490d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood for (int i = 0; i < count; i++) { 491d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.moveToNext(); 492d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood result[i] = c.getInt(0); 493d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 494d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return result; 495d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 496d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 497d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 498d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 499d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 500d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 501d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 502d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 503d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return null; 504d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 505d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 5067a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood private int getNumObjects(int storageID, int format, int parent) { 5077a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Cursor c = null; 5087a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood try { 509b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood c = createObjectQuery(storageID, format, parent); 5107a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 5117a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return c.getCount(); 5127a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 5137a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } catch (RemoteException e) { 5147a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood Log.e(TAG, "RemoteException in getNumObjects", e); 5157a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } finally { 5167a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood if (c != null) { 5177a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood c.close(); 5187a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 5197a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 5207a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood return -1; 5217a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood } 5227a047c89862febf63ce1bb5873179c7a2ff8d9d3Mike Lockwood 5234b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedPlaybackFormats() { 5244b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return new int[] { 525e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood // allow transfering arbitrary files 526e521169ff5dc6cbe1762bd7a049d95b56cc657eeMike Lockwood MtpConstants.FORMAT_UNDEFINED, 52712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood 528792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ASSOCIATION, 52912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TEXT, 53012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_HTML, 53112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WAV, 53212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP3, 53312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MPEG, 53412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_EXIF_JPEG, 53512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF_EP, 536240582eabee56d55751b85e220811d48fabe839abo huang MtpConstants.FORMAT_BMP, 53712b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_GIF, 53812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_JFIF, 53912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PNG, 54012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_TIFF, 54112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WMA, 54212b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_OGG, 54312b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_AAC, 54412b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP4_CONTAINER, 54512b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_MP2, 54612b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_3GP_CONTAINER, 547792ec849e5bc27c090c62f578846b888fa43e0d6Mike Lockwood MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST, 54812b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_WPL_PLAYLIST, 54912b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_M3U_PLAYLIST, 55012b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_PLS_PLAYLIST, 55112b8a99fc1d4acc427307a4a924bf33745410260Mike Lockwood MtpConstants.FORMAT_XML_DOCUMENT, 552f9f223edb408cdc9fd946dc099a86857079a639fGlenn Kasten MtpConstants.FORMAT_FLAC, 5534b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood }; 5544b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 5554b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 5564b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedCaptureFormats() { 5574b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood // no capture formats yet 5584b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood return null; 5594b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 5604b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 561ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] FILE_PROPERTIES = { 562ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match beginning of AUDIO_PROPERTIES, VIDEO_PROPERTIES 563ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // and IMAGE_PROPERTIES below 5645367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 5655367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 566d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 5675367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 5685367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 569d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 5705367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 571d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 572d3bfecb0c9bdf3651a06e86c7c8607768a29a9aeMike Lockwood MtpConstants.PROPERTY_NAME, 573ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 574ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 575ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 576ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] AUDIO_PROPERTIES = { 577ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 578ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 579ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 580ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 581ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 582ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 583ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 584ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 585ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 586ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 587ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 588ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 589ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 590ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // audio specific properties 591ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 592ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 593ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_ARTIST, 594ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_TRACK, 595ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, 596ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 597ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_GENRE, 598ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_COMPOSER, 599ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 600ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 601ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] VIDEO_PROPERTIES = { 602ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 603ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 604ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 605ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 606ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 607ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 608ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 609ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 610ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 611ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 612ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 613ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 614ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 615ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // video specific properties 616ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ARTIST, 617ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 618ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DURATION, 619ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 620ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 621ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 622ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood static final int[] IMAGE_PROPERTIES = { 623ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // NOTE must match FILE_PROPERTIES above 624ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 625ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 626ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 627ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 628ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 629ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 630ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 631ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 632ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_NAME, 633ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 634ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 635ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 636ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood // image specific properties 637ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 638ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood }; 639ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood 6407d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood static final int[] ALL_PROPERTIES = { 6417d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // NOTE must match FILE_PROPERTIES above 6427d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_STORAGE_ID, 6437d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_FORMAT, 6447d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PROTECTION_STATUS, 6457d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_SIZE, 6467d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_OBJECT_FILE_NAME, 6477d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DATE_MODIFIED, 6487d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PARENT_OBJECT, 6497d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_PERSISTENT_UID, 6507d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_NAME, 6517d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DISPLAY_NAME, 6527d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DATE_ADDED, 6537d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 6547d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // image specific properties 6557d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 6567d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 6577d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // audio specific properties 6587d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ARTIST, 6597d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 6607d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_ARTIST, 6617d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_TRACK, 6627d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, 6637d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DURATION, 6647d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_GENRE, 6657d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_COMPOSER, 6667d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 6677d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // video specific properties 6687d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ARTIST, 6697d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_ALBUM_NAME, 6707d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DURATION, 6717d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 6727d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 6737d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood // image specific properties 6747d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpConstants.PROPERTY_DESCRIPTION, 6757d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood }; 6767d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 677ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood private int[] getSupportedObjectProperties(int format) { 678ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood switch (format) { 679ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MP3: 680ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WAV: 681ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMA: 682ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_OGG: 683ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_AAC: 684ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return AUDIO_PROPERTIES; 685ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_MPEG: 686ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_3GP_CONTAINER: 687ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_WMV: 688ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return VIDEO_PROPERTIES; 689ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_EXIF_JPEG: 690ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_GIF: 691ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_PNG: 692ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood case MtpConstants.FORMAT_BMP: 693ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return IMAGE_PROPERTIES; 6947d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood case 0: 6957d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood return ALL_PROPERTIES; 696ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood default: 697ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood return FILE_PROPERTIES; 698ae078f7dacdc719d045c2d19bbce019599fec64eMike Lockwood } 6994b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 7004b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 7014b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood private int[] getSupportedDeviceProperties() { 70259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return new int[] { 70359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, 70459e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, 705ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, 70656c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL, 70759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood }; 7084b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood } 7094b322ce4fb86b5a7a6e50633a3a9f498ca8d4706Mike Lockwood 710e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 7117d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood private MtpPropertyList getObjectPropertyList(long handle, int format, long property, 712e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int groupCode, int depth) { 713e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // FIXME - implement group support 714e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (groupCode != 0) { 715e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED); 7165ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 7175ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 7187d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood MtpPropertyGroup propertyGroup; 7197d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (property == 0xFFFFFFFFL) { 7207d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = mPropertyGroupsByFormat.get(format); 7217d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (propertyGroup == null) { 7227d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood int[] propertyList = getSupportedObjectProperties(format); 72335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mPackageName, 72435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mVolumeName, propertyList); 7257d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood mPropertyGroupsByFormat.put(new Integer(format), propertyGroup); 726e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 7277d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood } else { 7287d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood propertyGroup = mPropertyGroupsByProperty.get(property); 7297d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood if (propertyGroup == null) { 7307d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood int[] propertyList = new int[] { (int)property }; 73135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mPackageName, 73235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mVolumeName, propertyList); 7337d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood mPropertyGroupsByProperty.put(new Integer((int)property), propertyGroup); 734e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 735e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 7367d7fb63071ca370f77ed69055ac30341b8388d15Mike Lockwood 737b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood return propertyGroup.getPropertyList((int)handle, format, depth); 738e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 739e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 740e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood private int renameFile(int handle, String newName) { 741e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Cursor c = null; 742e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 743e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // first compute current path 744e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String path = null; 745e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String[] whereArgs = new String[] { Integer.toString(handle) }; 746e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood try { 74735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, mObjectsUri, PATH_PROJECTION, ID_WHERE, 74835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn whereArgs, null, null); 749e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (c != null && c.moveToNext()) { 7501c4e88d0b0a8deede0415183739478b5ebc12bfdMike Lockwood path = c.getString(1); 751e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 752e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } catch (RemoteException e) { 753e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 754e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 755e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } finally { 756e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (c != null) { 757e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood c.close(); 758b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 759b2cada9034436b4ea4bac218da7a1e29460d15b2Mike Lockwood } 760e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (path == null) { 761e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 762e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 763e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 76473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // do not allow renaming any of the special subdirectories 76573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (isStorageSubDirectory(path)) { 76673e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; 76773e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 76873e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 769e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // now rename the file. make sure this succeeds before updating database 770e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood File oldFile = new File(path); 771e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int lastSlash = path.lastIndexOf('/'); 772e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (lastSlash <= 1) { 773e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 774e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 775e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood String newPath = path.substring(0, lastSlash + 1) + newName; 776e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood File newFile = new File(newPath); 777e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood boolean success = oldFile.renameTo(newFile); 778e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (!success) { 779f26a586c86b097f975e26fe526ead564ad011bd0Mike Lockwood Log.w(TAG, "renaming "+ path + " to " + newPath + " failed"); 780e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 781e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 782e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 783e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // finally update database 784e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood ContentValues values = new ContentValues(); 785e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood values.put(Files.FileColumns.DATA, newPath); 786e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood int updated = 0; 787e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood try { 788e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // note - we are relying on a special case in MediaProvider.update() to update 789e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // the paths for all children in the case where this is a directory. 79035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn updated = mMediaProvider.update(mPackageName, mObjectsUri, values, ID_WHERE, whereArgs); 791e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } catch (RemoteException e) { 792e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "RemoteException in mMediaProvider.update", e); 793e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 794e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood if (updated == 0) { 795e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood Log.e(TAG, "Unable to update path for " + path + " to " + newPath); 796e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood // this shouldn't happen, but if it does we need to rename the file to its original name 797e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood newFile.renameTo(oldFile); 798e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 799e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood } 800e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood 801ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen // check if nomedia status changed 802ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen if (newFile.isDirectory()) { 803ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen // for directories, check if renamed from something hidden to something non-hidden 804ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen if (oldFile.getName().startsWith(".") && !newPath.startsWith(".")) { 805ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen // directory was unhidden 806ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen try { 80735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mMediaProvider.call(mPackageName, MediaStore.UNHIDE_CALL, newPath, null); 808ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } catch (RemoteException e) { 809ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen Log.e(TAG, "failed to unhide/rescan for " + newPath); 810ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 811ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 812ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } else { 813ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen // for files, check if renamed from .nomedia to something else 814ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen if (oldFile.getName().toLowerCase(Locale.US).equals(".nomedia") 815ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen && !newPath.toLowerCase(Locale.US).equals(".nomedia")) { 816ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen try { 81735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mMediaProvider.call(mPackageName, MediaStore.UNHIDE_CALL, oldFile.getParent(), null); 818ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } catch (RemoteException e) { 819ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen Log.e(TAG, "failed to unhide/rescan for " + newPath); 820ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 821ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 822ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 823ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen 824e2ad6ec1718ef0c0e8230f8f62e7cfefcf598b6aMike Lockwood return MtpConstants.RESPONSE_OK; 825d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 826d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 82759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setObjectProperty(int handle, int property, 82859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood long intValue, String stringValue) { 8295ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood switch (property) { 8305ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood case MtpConstants.PROPERTY_OBJECT_FILE_NAME: 8315ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return renameFile(handle, stringValue); 8325ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood 8335ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood default: 8345ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood return MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED; 8355ebac83e20dadf10bd4a0cee4ddf69d0ec049f98Mike Lockwood } 83659e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 83759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 83859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { 83959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 84059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 84159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 842775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood // writable string properties kept in shared preferences 843775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood String value = mDeviceProperties.getString(Integer.toString(property), ""); 844775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood int length = value.length(); 845775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood if (length > 255) { 846775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood length = 255; 84759e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 848775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood value.getChars(0, length, outStringValue, 0); 849775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood outStringValue[length] = 0; 850775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood return MtpConstants.RESPONSE_OK; 85159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 852ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood case MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE: 853ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood // use screen size as max image size 854ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood Display display = ((WindowManager)mContext.getSystemService( 855ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood Context.WINDOW_SERVICE)).getDefaultDisplay(); 85644bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn int width = display.getMaximumSizeDimension(); 85744bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn int height = display.getMaximumSizeDimension(); 858ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood String imageSize = Integer.toString(width) + "x" + Integer.toString(height); 859ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood imageSize.getChars(0, imageSize.length(), outStringValue, 0); 860ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood outStringValue[imageSize.length()] = 0; 861ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood return MtpConstants.RESPONSE_OK; 862ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood 86356c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood // DEVICE_PROPERTY_BATTERY_LEVEL is implemented in the JNI code 86456c85244b9be0fc6f6c2baf5f9a53f2364d5ec5eMike Lockwood 865ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood default: 866ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 867ea93fa16b166ff477e9cf6bd3ac67c8fb259fb57Mike Lockwood } 86859e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 86959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 87059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood private int setDeviceProperty(int property, long intValue, String stringValue) { 87159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood switch (property) { 87259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: 87359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: 874775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood // writable string properties kept in shared prefs 875775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood SharedPreferences.Editor e = mDeviceProperties.edit(); 876775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood e.putString(Integer.toString(property), stringValue); 877775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood return (e.commit() ? MtpConstants.RESPONSE_OK 878775de951a8d4f4fe58c849efd9ef7b92c4ade907Mike Lockwood : MtpConstants.RESPONSE_GENERAL_ERROR); 87959e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 88059e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 88159e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; 88259e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood } 88359e3f0db0855567a95f783f6d1ec36a7cfc4ea83Mike Lockwood 884d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private boolean getObjectInfo(int handle, int[] outStorageFormatParent, 8851341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood char[] outName, long[] outCreatedModified) { 886d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 887d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 88835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, mObjectsUri, OBJECT_INFO_PROJECTION, 88975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown ID_WHERE, new String[] { Integer.toString(handle) }, null, null); 890d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 891b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood outStorageFormatParent[0] = c.getInt(1); 892d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[1] = c.getInt(2); 893d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outStorageFormatParent[2] = c.getInt(3); 894d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 895d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // extract name from path 896b239b683765f63d79e74b8ba2a8cc2855f236536Mike Lockwood String path = c.getString(4); 897d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int lastSlash = path.lastIndexOf('/'); 898d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int start = (lastSlash >= 0 ? lastSlash + 1 : 0); 899d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood int end = path.length(); 900d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (end - start > 255) { 901d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood end = start + 255; 902d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 903d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(start, end, outName, 0); 904d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outName[end - start] = 0; 905d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 9061341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood outCreatedModified[0] = c.getLong(5); 9071341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood outCreatedModified[1] = c.getLong(6); 9081341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood // use modification date as creation date if date added is not set 9091341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood if (outCreatedModified[0] == 0) { 9101341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood outCreatedModified[0] = outCreatedModified[1]; 9111341f1eee3493fc5e263494acb8adebb6f0180b6Mike Lockwood } 912d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return true; 913d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 914d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 9152b5f9ad1eaf0d6daaca5cf3761434a09309902bbMike Lockwood Log.e(TAG, "RemoteException in getObjectInfo", e); 916d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 917d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 918d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 919d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 920d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 921d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood return false; 922d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 923d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 924365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLengthFormat) { 92501788562f26f213f63c14483fd3977e23b8314abMike Lockwood if (handle == 0) { 92601788562f26f213f63c14483fd3977e23b8314abMike Lockwood // special case root directory 92701788562f26f213f63c14483fd3977e23b8314abMike Lockwood mMediaStoragePath.getChars(0, mMediaStoragePath.length(), outFilePath, 0); 92801788562f26f213f63c14483fd3977e23b8314abMike Lockwood outFilePath[mMediaStoragePath.length()] = 0; 929365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[0] = 0; 930365e03e4943b2d2f4d1e602409ab0e770ea77d1dMike Lockwood outFileLengthFormat[1] = MtpConstants.FORMAT_ASSOCIATION; 93101788562f26f213f63c14483fd3977e23b8314abMike Lockwood return MtpConstants.RESPONSE_OK; 93201788562f26f213f63c14483fd3977e23b8314abMike Lockwood } 933d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Cursor c = null; 934d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 93535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, mObjectsUri, PATH_FORMAT_PROJECTION, 93675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown ID_WHERE, new String[] { Integer.toString(handle) }, null, null); 937d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null && c.moveToNext()) { 9381c4e88d0b0a8deede0415183739478b5ebc12bfdMike Lockwood String path = c.getString(1); 939d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood path.getChars(0, path.length(), outFilePath, 0); 940d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood outFilePath[path.length()] = 0; 941f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood // File transfers from device to host will likely fail if the size is incorrect. 942f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood // So to be safe, use the actual file size here. 943f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood outFileLengthFormat[0] = new File(path).length(); 944f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood outFileLengthFormat[1] = c.getLong(2); 9455367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 94659c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 9475367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 948d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 949d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 950d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in getObjectFilePath", e); 9515367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 952d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } finally { 953d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood if (c != null) { 954d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood c.close(); 955d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 956d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 957d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 958d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 95959c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood private int deleteFile(int handle) { 9602837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 96155f808cff9913a00164120a422af6ca45db5072bMike Lockwood String path = null; 96255f808cff9913a00164120a422af6ca45db5072bMike Lockwood int format = 0; 96355f808cff9913a00164120a422af6ca45db5072bMike Lockwood 96455f808cff9913a00164120a422af6ca45db5072bMike Lockwood Cursor c = null; 965d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood try { 96635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, mObjectsUri, PATH_FORMAT_PROJECTION, 96775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown ID_WHERE, new String[] { Integer.toString(handle) }, null, null); 96855f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (c != null && c.moveToNext()) { 96955f808cff9913a00164120a422af6ca45db5072bMike Lockwood // don't convert to media path here, since we will be matching 97055f808cff9913a00164120a422af6ca45db5072bMike Lockwood // against paths in the database matching /data/media 97155f808cff9913a00164120a422af6ca45db5072bMike Lockwood path = c.getString(1); 972f6f16614574767263fcd0073f72c099edaca0607Mike Lockwood format = c.getInt(2); 97355f808cff9913a00164120a422af6ca45db5072bMike Lockwood } else { 97455f808cff9913a00164120a422af6ca45db5072bMike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 97555f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 97655f808cff9913a00164120a422af6ca45db5072bMike Lockwood 97755f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (path == null || format == 0) { 97855f808cff9913a00164120a422af6ca45db5072bMike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 97955f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 98055f808cff9913a00164120a422af6ca45db5072bMike Lockwood 98173e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood // do not allow deleting any of the special subdirectories 98273e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood if (isStorageSubDirectory(path)) { 98373e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; 98473e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood } 98573e56d935e7c9b8a06e4781c4995e407e118f93dMike Lockwood 98655f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (format == MtpConstants.FORMAT_ASSOCIATION) { 98755f808cff9913a00164120a422af6ca45db5072bMike Lockwood // recursive case - delete all children first 98855f808cff9913a00164120a422af6ca45db5072bMike Lockwood Uri uri = Files.getMtpObjectsUri(mVolumeName); 98935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int count = mMediaProvider.delete(mPackageName, uri, 9901e855d98aa979b30cee9e096cf6a1cb54df0367bMike Lockwood // the 'like' makes it use the index, the 'lower()' makes it correct 9911e855d98aa979b30cee9e096cf6a1cb54df0367bMike Lockwood // when the path contains sqlite wildcard characters 9921e855d98aa979b30cee9e096cf6a1cb54df0367bMike Lockwood "_data LIKE ?1 AND lower(substr(_data,1,?2))=lower(?3)", 9931e855d98aa979b30cee9e096cf6a1cb54df0367bMike Lockwood new String[] { path + "/%",Integer.toString(path.length() + 1), path + "/"}); 99455f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 99555f808cff9913a00164120a422af6ca45db5072bMike Lockwood 99655f808cff9913a00164120a422af6ca45db5072bMike Lockwood Uri uri = Files.getMtpObjectsUri(mVolumeName, handle); 99735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mMediaProvider.delete(mPackageName, uri, null, null) > 0) { 998ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen if (format != MtpConstants.FORMAT_ASSOCIATION 999ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen && path.toLowerCase(Locale.US).endsWith("/.nomedia")) { 1000ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen try { 1001ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen String parentPath = path.substring(0, path.lastIndexOf("/")); 100235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mMediaProvider.call(mPackageName, MediaStore.UNHIDE_CALL, parentPath, null); 1003ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } catch (RemoteException e) { 1004ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen Log.e(TAG, "failed to unhide/rescan for " + path); 1005ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 1006ca78f3d9aff78c35bc065b0c35a0b3c917f56435Marco Nelissen } 10075367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 100859c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } else { 10095367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; 101059c777a24a2c639dfd84b7bf17e430e6d3424866Mike Lockwood } 1011d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } catch (RemoteException e) { 1012d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood Log.e(TAG, "RemoteException in deleteFile", e); 10135367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 101455f808cff9913a00164120a422af6ca45db5072bMike Lockwood } finally { 101555f808cff9913a00164120a422af6ca45db5072bMike Lockwood if (c != null) { 101655f808cff9913a00164120a422af6ca45db5072bMike Lockwood c.close(); 101755f808cff9913a00164120a422af6ca45db5072bMike Lockwood } 1018d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 1019d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood } 1020d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 10219a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int[] getObjectReferences(int handle) { 10228490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 10239a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Cursor c = null; 10249a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 102535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn c = mMediaProvider.query(mPackageName, uri, ID_PROJECTION, null, null, null, null); 10269a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c == null) { 10279a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 10289a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10299a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = c.getCount(); 10309a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (count > 0) { 10319a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int[] result = new int[count]; 10329a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 10339a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.moveToNext(); 10349a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood result[i] = c.getInt(0); 10359a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10369a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return result; 10379a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10389a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 10399a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in getObjectList", e); 10409a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } finally { 10419a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood if (c != null) { 10429a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood c.close(); 10439a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10449a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10459a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood return null; 10469a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10479a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 10489a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood private int setObjectReferences(int handle, int[] references) { 10492837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = true; 10508490e66f57506d4e4b05e7c987c7ca34295843e6Mike Lockwood Uri uri = Files.getMtpReferencesUri(mVolumeName, handle); 10519a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood int count = references.length; 10529a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues[] valuesList = new ContentValues[count]; 10539a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood for (int i = 0; i < count; i++) { 10549a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood ContentValues values = new ContentValues(); 10553b2a62e5b35ea5f8da9d9bee52f75c9c2ebb4eceMike Lockwood values.put(Files.FileColumns._ID, references[i]); 10569a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood valuesList[i] = values; 10579a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10589a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood try { 105935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mMediaProvider.bulkInsert(mPackageName, uri, valuesList) > 0) { 10605367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_OK; 10619a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10629a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } catch (RemoteException e) { 10639a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood Log.e(TAG, "RemoteException in setObjectReferences", e); 10649a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10655367ab6aab2a61aaf534b18576dcdd0bca1b9681Mike Lockwood return MtpConstants.RESPONSE_GENERAL_ERROR; 10669a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood } 10679a2046fb5ceeee4d5334274cbff15f1058bb3244Mike Lockwood 10682837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionStarted() { 10692837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 10702837eefc5459427138c080d445bb491c75630163Mike Lockwood } 10712837eefc5459427138c080d445bb491c75630163Mike Lockwood 10722837eefc5459427138c080d445bb491c75630163Mike Lockwood private void sessionEnded() { 10732837eefc5459427138c080d445bb491c75630163Mike Lockwood if (mDatabaseModified) { 1074a31560598af25d5116effc2a6af0d9be12a0628dMike Lockwood mContext.sendBroadcast(new Intent(MediaStore.ACTION_MTP_SESSION_END)); 10752837eefc5459427138c080d445bb491c75630163Mike Lockwood mDatabaseModified = false; 10762837eefc5459427138c080d445bb491c75630163Mike Lockwood } 10772837eefc5459427138c080d445bb491c75630163Mike Lockwood } 10782837eefc5459427138c080d445bb491c75630163Mike Lockwood 1079d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood // used by the JNI code 1080e2e59326f13cf291bf5b37989390fd2a55a94f0cAshok Bhat private long mNativeContext; 1081d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood 1082d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_setup(); 1083d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood private native final void native_finalize(); 1084d21eac9c70940f2c73da5faaf401dbbc44b70a15Mike Lockwood} 1085