diff options
author | Mike Lockwood <lockwood@google.com> | 2011-12-01 16:58:41 -0500 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2011-12-02 11:08:39 -0500 |
commit | 73e56d935e7c9b8a06e4781c4995e407e118f93d (patch) | |
tree | f35e4e26f2be4e533528ffc41ebd101ee1fc2abd /media/java | |
parent | 1958dc27c952da3a590750023e391e0d481a4328 (diff) | |
download | frameworks_base-73e56d935e7c9b8a06e4781c4995e407e118f93d.zip frameworks_base-73e56d935e7c9b8a06e4781c4995e407e118f93d.tar.gz frameworks_base-73e56d935e7c9b8a06e4781c4995e407e118f93d.tar.bz2 |
MTP: Add support for restricting PTP to only certain subdirectories of the storage
Bug: 5527220
Change-Id: If68e7481617ecb62abd24e2d89e6b7dfdf95ba2b
Signed-off-by: Mike Lockwood <lockwood@google.com>
Diffstat (limited to 'media/java')
-rwxr-xr-x | media/java/android/mtp/MtpDatabase.java | 188 |
1 files changed, 150 insertions, 38 deletions
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index 98617d2..19db1c0 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -51,7 +51,15 @@ public class MtpDatabase { private final IContentProvider mMediaProvider; private final String mVolumeName; private final Uri mObjectsUri; - private final String mMediaStoragePath; // path to primary storage + // path to primary storage + private final String mMediaStoragePath; + // if not null, restrict all queries to these subdirectories + private final String[] mSubDirectories; + // where clause for restricting queries to files in mSubDirectories + private String mSubDirectoriesWhere; + // where arguments for restricting queries to files in mSubDirectories + private String[] mSubDirectoriesWhereArgs; + private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>(); // cached property groups for single properties @@ -112,7 +120,8 @@ public class MtpDatabase { System.loadLibrary("media_jni"); } - public MtpDatabase(Context context, String volumeName, String storagePath) { + public MtpDatabase(Context context, String volumeName, String storagePath, + String[] subDirectories) { native_setup(); mContext = context; @@ -122,6 +131,31 @@ public class MtpDatabase { mObjectsUri = Files.getMtpObjectsUri(volumeName); mMediaScanner = new MediaScanner(context); + mSubDirectories = subDirectories; + if (subDirectories != null) { + // Compute "where" string for restricting queries to subdirectories + StringBuilder builder = new StringBuilder(); + builder.append("("); + int count = subDirectories.length; + for (int i = 0; i < count; i++) { + builder.append(Files.FileColumns.DATA + "=? OR " + + Files.FileColumns.DATA + " LIKE ?"); + if (i != count - 1) { + builder.append(" OR "); + } + } + builder.append(")"); + mSubDirectoriesWhere = builder.toString(); + + // Compute "where" arguments for restricting queries to subdirectories + mSubDirectoriesWhereArgs = new String[count * 2]; + for (int i = 0, j = 0; i < count; i++) { + String path = subDirectories[i]; + mSubDirectoriesWhereArgs[j++] = path; + mSubDirectoriesWhereArgs[j++] = path + "/%"; + } + } + // Set locale to MediaScanner. Locale locale = context.getResources().getConfiguration().locale; if (locale != null) { @@ -190,9 +224,44 @@ public class MtpDatabase { } } + // check to see if the path is contained in one of our storage subdirectories + // returns true if we have no special subdirectories + private boolean inStorageSubDirectory(String path) { + if (mSubDirectories == null) return true; + if (path == null) return false; + + boolean allowed = false; + int pathLength = path.length(); + for (int i = 0; i < mSubDirectories.length && !allowed; i++) { + String subdir = mSubDirectories[i]; + int subdirLength = subdir.length(); + if (subdirLength < pathLength && + path.charAt(subdirLength) == '/' && + path.startsWith(subdir)) { + allowed = true; + } + } + return allowed; + } + + // check to see if the path matches one of our storage subdirectories + // returns true if we have no special subdirectories + private boolean isStorageSubDirectory(String path) { + if (mSubDirectories == null) return false; + for (int i = 0; i < mSubDirectories.length; i++) { + if (path.equals(mSubDirectories[i])) { + return true; + } + } + return false; + } + private int beginSendObject(String path, int format, int parent, int storageId, long size, long modified) { - // first make sure the object does not exist + // if mSubDirectories is not null, do not allow copying files to any other locations + if (!inStorageSubDirectory(path)) return -1; + + // make sure the object does not exist if (path != null) { Cursor c = null; try { @@ -269,33 +338,40 @@ public class MtpDatabase { } private Cursor createObjectQuery(int storageID, int format, int parent) throws RemoteException { + String where; + String[] whereArgs; + if (storageID == 0xFFFFFFFF) { // query all stores if (format == 0) { // query all formats if (parent == 0) { // query all objects - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, null, null, null); - } - if (parent == 0xFFFFFFFF) { - // all objects in root of store - parent = 0; + where = null; + whereArgs = null; + } else { + if (parent == 0xFFFFFFFF) { + // all objects in root of store + parent = 0; + } + where = PARENT_WHERE; + whereArgs = new String[] { Integer.toString(parent) }; } - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, PARENT_WHERE, - new String[] { Integer.toString(parent) }, null); } else { // query specific format if (parent == 0) { // query all objects - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, FORMAT_WHERE, - new String[] { Integer.toString(format) }, null); - } - if (parent == 0xFFFFFFFF) { - // all objects in root of store - parent = 0; + where = FORMAT_WHERE; + whereArgs = new String[] { Integer.toString(format) }; + } else { + if (parent == 0xFFFFFFFF) { + // all objects in root of store + parent = 0; + } + where = FORMAT_PARENT_WHERE; + whereArgs = new String[] { Integer.toString(format), + Integer.toString(parent) }; } - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, FORMAT_PARENT_WHERE, - new String[] { Integer.toString(format), Integer.toString(parent) }, null); } } else { // query specific store @@ -303,35 +379,61 @@ public class MtpDatabase { // query all formats if (parent == 0) { // query all objects - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_WHERE, - new String[] { Integer.toString(storageID) }, null); - } - if (parent == 0xFFFFFFFF) { - // all objects in root of store - parent = 0; + where = STORAGE_WHERE; + whereArgs = new String[] { Integer.toString(storageID) }; + } else { + if (parent == 0xFFFFFFFF) { + // all objects in root of store + parent = 0; + } + where = STORAGE_PARENT_WHERE; + whereArgs = new String[] { Integer.toString(storageID), + Integer.toString(parent) }; } - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_PARENT_WHERE, - new String[] { Integer.toString(storageID), Integer.toString(parent) }, - null); } else { // query specific format if (parent == 0) { // query all objects - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_FORMAT_WHERE, - new String[] { Integer.toString(storageID), Integer.toString(format) }, - null); + where = STORAGE_FORMAT_WHERE; + whereArgs = new String[] { Integer.toString(storageID), + Integer.toString(format) }; + } else { + if (parent == 0xFFFFFFFF) { + // all objects in root of store + parent = 0; + } + where = STORAGE_FORMAT_PARENT_WHERE; + whereArgs = new String[] { Integer.toString(storageID), + Integer.toString(format), + Integer.toString(parent) }; } - if (parent == 0xFFFFFFFF) { - // all objects in root of store - parent = 0; + } + } + + // if we are restricting queries to mSubDirectories, we need to add the restriction + // onto our "where" arguments + if (mSubDirectoriesWhere != null) { + if (where == null) { + where = mSubDirectoriesWhere; + whereArgs = mSubDirectoriesWhereArgs; + } else { + where = where + " AND " + mSubDirectoriesWhere; + + // create new array to hold whereArgs and mSubDirectoriesWhereArgs + String[] newWhereArgs = + new String[whereArgs.length + mSubDirectoriesWhereArgs.length]; + int i, j; + for (i = 0; i < whereArgs.length; i++) { + newWhereArgs[i] = whereArgs[i]; } - return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_FORMAT_PARENT_WHERE, - new String[] { Integer.toString(storageID), - Integer.toString(format), - Integer.toString(parent) }, - null); + for (j = 0; j < mSubDirectoriesWhereArgs.length; i++, j++) { + newWhereArgs[i] = mSubDirectoriesWhereArgs[j]; + } + whereArgs = newWhereArgs; } } + + return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null); } private int[] getObjectList(int storageID, int format, int parent) { @@ -613,6 +715,11 @@ public class MtpDatabase { return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE; } + // do not allow renaming any of the special subdirectories + if (isStorageSubDirectory(path)) { + return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; + } + // now rename the file. make sure this succeeds before updating database File oldFile = new File(path); int lastSlash = path.lastIndexOf('/'); @@ -794,6 +901,11 @@ public class MtpDatabase { return MtpConstants.RESPONSE_GENERAL_ERROR; } + // do not allow deleting any of the special subdirectories + if (isStorageSubDirectory(path)) { + return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED; + } + if (format == MtpConstants.FORMAT_ASSOCIATION) { // recursive case - delete all children first Uri uri = Files.getMtpObjectsUri(mVolumeName); |