summaryrefslogtreecommitdiffstats
path: root/media/java
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2011-04-05 10:21:27 -0400
committerMike Lockwood <lockwood@android.com>2011-05-04 10:41:20 -0400
commitd3e4290c0442b6dcf24bcf642f4fc26d12d8e7aa (patch)
tree4604a25cd5f0617b9667f7b2d03ab56d57e13207 /media/java
parent10fbba21e4827a1582d97aa99e4e8d772ce04920 (diff)
downloadframeworks_base-d3e4290c0442b6dcf24bcf642f4fc26d12d8e7aa.zip
frameworks_base-d3e4290c0442b6dcf24bcf642f4fc26d12d8e7aa.tar.gz
frameworks_base-d3e4290c0442b6dcf24bcf642f4fc26d12d8e7aa.tar.bz2
DO NOT MERGE MTP and media provider support for multiple storage devices:
- MTP support for multiple storage units - Add storage_id column to media database for MTP storage ID - Add framework resource for defining mount points and user visible descriptions for multiple volumes - Clean up locking in MtpServer JNI code Change-Id: I53d501fd4891ebe27408135fb598027e06b7e495 Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media/java')
-rw-r--r--media/java/android/mtp/MtpDatabase.java78
-rw-r--r--media/java/android/mtp/MtpPropertyGroup.java11
-rw-r--r--media/java/android/mtp/MtpServer.java20
-rw-r--r--media/java/android/mtp/MtpStorage.java89
4 files changed, 152 insertions, 46 deletions
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index b4a4689..b900671 100644
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -50,7 +50,8 @@ public class MtpDatabase {
private final IContentProvider mMediaProvider;
private final String mVolumeName;
private final Uri mObjectsUri;
- private final String mMediaStoragePath;
+ private final String mMediaStoragePath; // path to primary storage
+ private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>();
// cached property groups for single properties
private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByProperty
@@ -67,9 +68,6 @@ public class MtpDatabase {
private SharedPreferences mDeviceProperties;
private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1;
- // FIXME - this should be passed in via the constructor
- private final int mStorageID = 0x00010001;
-
private static final String[] ID_PROJECTION = new String[] {
Files.FileColumns._ID, // 0
};
@@ -85,17 +83,22 @@ public class MtpDatabase {
};
private static final String[] OBJECT_INFO_PROJECTION = new String[] {
Files.FileColumns._ID, // 0
- Files.FileColumns.DATA, // 1
+ Files.FileColumns.STORAGE_ID, // 1
Files.FileColumns.FORMAT, // 2
Files.FileColumns.PARENT, // 3
- Files.FileColumns.SIZE, // 4
- Files.FileColumns.DATE_MODIFIED, // 5
+ Files.FileColumns.DATA, // 4
+ Files.FileColumns.SIZE, // 5
+ Files.FileColumns.DATE_MODIFIED, // 6
};
private static final String ID_WHERE = Files.FileColumns._ID + "=?";
private static final String PATH_WHERE = Files.FileColumns.DATA + "=?";
private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
+ Files.FileColumns.FORMAT + "=?";
+ private static final String PARENT_STORAGE_WHERE = PARENT_WHERE + " AND "
+ + Files.FileColumns.STORAGE_ID + "=?";
+ private static final String PARENT_STORAGE_FORMAT_WHERE = PARENT_STORAGE_WHERE + " AND "
+ + Files.FileColumns.FORMAT + "=?";
private final MediaScanner mMediaScanner;
@@ -124,6 +127,14 @@ public class MtpDatabase {
}
}
+ public void addStorage(MtpStorage storage) {
+ mStorageMap.put(storage.getPath(), storage);
+ }
+
+ public void removeStorage(MtpStorage storage) {
+ mStorageMap.remove(storage.getPath());
+ }
+
private void initDeviceProperties(Context context) {
final String devicePropertiesName = "device-properties";
mDeviceProperties = context.getSharedPreferences(devicePropertiesName, Context.MODE_PRIVATE);
@@ -160,7 +171,7 @@ public class MtpDatabase {
}
private int beginSendObject(String path, int format, int parent,
- int storage, long size, long modified) {
+ int storageId, long size, long modified) {
// first make sure the object does not exist
if (path != null) {
Cursor c = null;
@@ -185,7 +196,7 @@ public class MtpDatabase {
values.put(Files.FileColumns.DATA, path);
values.put(Files.FileColumns.FORMAT, format);
values.put(Files.FileColumns.PARENT, parent);
- // storage is ignored for now
+ values.put(Files.FileColumns.STORAGE_ID, storageId);
values.put(Files.FileColumns.SIZE, size);
values.put(Files.FileColumns.DATE_MODIFIED, modified);
@@ -237,19 +248,35 @@ public class MtpDatabase {
}
}
- private int[] getObjectList(int storageID, int format, int parent) {
- // we can ignore storageID until we support multiple storages
- Cursor c = null;
- try {
+ private Cursor createObjectQuery(int storageID, int format, int parent) throws RemoteException {
+ if (storageID != 0) {
+ if (format != 0) {
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION,
+ PARENT_STORAGE_FORMAT_WHERE,
+ new String[] { Integer.toString(parent), Integer.toString(storageID),
+ Integer.toString(format) }, null);
+ } else {
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION,
+ PARENT_STORAGE_WHERE, new String[]
+ { Integer.toString(parent), Integer.toString(storageID) }, null);
+ }
+ } else {
if (format != 0) {
- c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION,
PARENT_FORMAT_WHERE,
new String[] { Integer.toString(parent), Integer.toString(format) },
null);
} else {
- c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION,
PARENT_WHERE, new String[] { Integer.toString(parent) }, null);
}
+ }
+ }
+
+ private int[] getObjectList(int storageID, int format, int parent) {
+ Cursor c = null;
+ try {
+ c = createObjectQuery(storageID, format, parent);
if (c == null) {
return null;
}
@@ -273,18 +300,9 @@ public class MtpDatabase {
}
private int getNumObjects(int storageID, int format, int parent) {
- // we can ignore storageID until we support multiple storages
Cursor c = null;
try {
- if (format != 0) {
- c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
- PARENT_FORMAT_WHERE,
- new String[] { Integer.toString(parent), Integer.toString(format) },
- null);
- } else {
- c = mMediaProvider.query(mObjectsUri, ID_PROJECTION,
- PARENT_WHERE, new String[] { Integer.toString(parent) }, null);
- }
+ c = createObjectQuery(storageID, format, parent);
if (c != null) {
return c.getCount();
}
@@ -508,7 +526,7 @@ public class MtpDatabase {
}
}
- return propertyGroup.getPropertyList((int)handle, format, depth, mStorageID);
+ return propertyGroup.getPropertyList((int)handle, format, depth);
}
private int renameFile(int handle, String newName) {
@@ -631,12 +649,12 @@ public class MtpDatabase {
c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
ID_WHERE, new String[] { Integer.toString(handle) }, null);
if (c != null && c.moveToNext()) {
- outStorageFormatParent[0] = mStorageID;
+ outStorageFormatParent[0] = c.getInt(1);
outStorageFormatParent[1] = c.getInt(2);
outStorageFormatParent[2] = c.getInt(3);
// extract name from path
- String path = c.getString(1);
+ String path = c.getString(4);
int lastSlash = path.lastIndexOf('/');
int start = (lastSlash >= 0 ? lastSlash + 1 : 0);
int end = path.length();
@@ -646,8 +664,8 @@ public class MtpDatabase {
path.getChars(start, end, outName, 0);
outName[end - start] = 0;
- outSizeModified[0] = c.getLong(4);
- outSizeModified[1] = c.getLong(5);
+ outSizeModified[0] = c.getLong(5);
+ outSizeModified[1] = c.getLong(6);
return true;
}
} catch (RemoteException e) {
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index fceedd2..b75b11a 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -93,7 +93,7 @@ class MtpPropertyGroup {
switch (code) {
case MtpConstants.PROPERTY_STORAGE_ID:
- // no query needed until we support multiple storage units
+ column = Files.FileColumns.STORAGE_ID;
type = MtpConstants.TYPE_UINT32;
break;
case MtpConstants.PROPERTY_OBJECT_FORMAT:
@@ -134,6 +134,7 @@ class MtpPropertyGroup {
break;
case MtpConstants.PROPERTY_PERSISTENT_UID:
// PUID is concatenation of storageID and object handle
+ column = Files.FileColumns.STORAGE_ID;
type = MtpConstants.TYPE_UINT128;
break;
case MtpConstants.PROPERTY_DURATION:
@@ -280,7 +281,7 @@ class MtpPropertyGroup {
return path.substring(start, end);
}
- MtpPropertyList getPropertyList(int handle, int format, int depth, int storageID) {
+ MtpPropertyList getPropertyList(int handle, int format, int depth) {
//Log.d(TAG, "getPropertyList handle: " + handle + " format: " + format + " depth: " + depth);
if (depth > 1) {
// we only support depth 0 and 1
@@ -348,10 +349,6 @@ class MtpPropertyGroup {
// handle some special cases
switch (propertyCode) {
- case MtpConstants.PROPERTY_STORAGE_ID:
- result.append(handle, propertyCode, MtpConstants.TYPE_UINT32,
- storageID);
- break;
case MtpConstants.PROPERTY_PROTECTION_STATUS:
// protection status is always 0
result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0);
@@ -398,7 +395,7 @@ class MtpPropertyGroup {
break;
case MtpConstants.PROPERTY_PERSISTENT_UID:
// PUID is concatenation of storageID and object handle
- long puid = storageID;
+ long puid = c.getLong(column);
puid <<= 32;
puid += handle;
result.append(handle, propertyCode, MtpConstants.TYPE_UINT128, puid);
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index 006fa6d..c065ca8 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -33,8 +33,8 @@ public class MtpServer {
System.loadLibrary("media_jni");
}
- public MtpServer(MtpDatabase database, String storagePath, long reserveSpace) {
- native_setup(database, storagePath, reserveSpace);
+ public MtpServer(MtpDatabase database) {
+ native_setup(database);
}
public void start() {
@@ -65,18 +65,20 @@ public class MtpServer {
native_set_ptp_mode(usePtp);
}
- // Used to disable MTP by removing all storage units.
- // This is done to disable access to file transfer when the device is locked.
- public void setLocked(boolean locked) {
- native_set_locked(locked);
+ public void addStorage(MtpStorage storage) {
+ native_add_storage(storage);
}
- private native final void native_setup(MtpDatabase database, String storagePath,
- long reserveSpace);
+ public void removeStorage(MtpStorage storage) {
+ native_remove_storage(storage.getStorageId());
+ }
+
+ private native final void native_setup(MtpDatabase database);
private native final void native_start();
private native final void native_stop();
private native final void native_send_object_added(int handle);
private native final void native_send_object_removed(int handle);
private native final void native_set_ptp_mode(boolean usePtp);
- private native final void native_set_locked(boolean locked);
+ private native final void native_add_storage(MtpStorage storage);
+ private native final void native_remove_storage(int storageId);
}
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
new file mode 100644
index 0000000..33146e7
--- /dev/null
+++ b/media/java/android/mtp/MtpStorage.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mtp;
+
+/**
+ * This class represents a storage unit on an MTP device.
+ * Used only for MTP support in USB responder mode.
+ * MtpStorageInfo is used in MTP host mode
+ *
+ * @hide
+ */
+public class MtpStorage {
+
+ private final int mStorageId;
+ private final String mPath;
+ private final String mDescription;
+ private final long mReserveSpace;
+
+ public MtpStorage(int id, String path, String description, long reserveSpace) {
+ mStorageId = id;
+ mPath = path;
+ mDescription = description;
+ mReserveSpace = reserveSpace;
+ }
+
+ /**
+ * Returns the storage ID for the storage unit
+ *
+ * @return the storage ID
+ */
+ public final int getStorageId() {
+ return mStorageId;
+ }
+
+ /**
+ * Generates a storage ID for storage of given index.
+ * Index 0 is for primary external storage
+ *
+ * @return the storage ID
+ */
+ public static int getStorageId(int index) {
+ // storage ID is 0x00010001 for primary storage,
+ // then 0x00020001, 0x00030001, etc. for secondary storages
+ return ((index + 1) << 16) + 1;
+ }
+
+ /**
+ * Returns the file path for the storage unit's storage in the file system
+ *
+ * @return the storage file path
+ */
+ public final String getPath() {
+ return mPath;
+ }
+
+ /**
+ * Returns the description string for the storage unit
+ *
+ * @return the storage unit description
+ */
+ public final String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Returns the amount of space to reserve on the storage file system.
+ * This can be set to a non-zero value to prevent MTP from filling up the entire storage.
+ *
+ * @return the storage unit description
+ */
+ public final long getReserveSpace() {
+ return mReserveSpace;
+ }
+
+}