diff options
-rw-r--r-- | core/java/android/os/storage/StorageVolume.java | 24 | ||||
-rwxr-xr-x | core/res/res/values/attrs.xml | 2 | ||||
-rw-r--r-- | media/java/android/mtp/MtpPropertyGroup.java | 1 | ||||
-rw-r--r-- | media/java/android/mtp/MtpStorage.java | 11 | ||||
-rw-r--r-- | media/jni/android_mtp_MtpServer.cpp | 10 | ||||
-rw-r--r-- | media/mtp/MtpServer.cpp | 8 | ||||
-rw-r--r-- | media/mtp/MtpStorage.cpp | 4 | ||||
-rw-r--r-- | media/mtp/MtpStorage.h | 4 | ||||
-rw-r--r-- | services/java/com/android/server/MountService.java | 8 |
9 files changed, 62 insertions, 10 deletions
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 792e4c1..60900e1 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -34,6 +34,8 @@ public class StorageVolume implements Parcelable { private final int mMtpReserveSpace; private final boolean mAllowMassStorage; private int mStorageId; + // maximum file size for the storage, or zero for no limit + private final long mMaxFileSize; // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING, // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED, @@ -41,18 +43,20 @@ public class StorageVolume implements Parcelable { public static final String EXTRA_STORAGE_VOLUME = "storage_volume"; public StorageVolume(String path, String description, boolean removable, - boolean emulated, int mtpReserveSpace, boolean allowMassStorage) { + boolean emulated, int mtpReserveSpace, boolean allowMassStorage, long maxFileSize) { mPath = path; mDescription = description; mRemovable = removable; mEmulated = emulated; mMtpReserveSpace = mtpReserveSpace; mAllowMassStorage = allowMassStorage; + mMaxFileSize = maxFileSize; } // for parcelling only private StorageVolume(String path, String description, boolean removable, - boolean emulated, int mtpReserveSpace, int storageId, boolean allowMassStorage) { + boolean emulated, int mtpReserveSpace, int storageId, + boolean allowMassStorage, long maxFileSize) { mPath = path; mDescription = description; mRemovable = removable; @@ -60,6 +64,7 @@ public class StorageVolume implements Parcelable { mMtpReserveSpace = mtpReserveSpace; mAllowMassStorage = allowMassStorage; mStorageId = storageId; + mMaxFileSize = maxFileSize; } /** @@ -142,6 +147,15 @@ public class StorageVolume implements Parcelable { return mAllowMassStorage; } + /** + * Returns maximum file size for the volume, or zero if it is unbounded. + * + * @return maximum file size + */ + public long getMaxFileSize() { + return mMaxFileSize; + } + @Override public boolean equals(Object obj) { if (obj instanceof StorageVolume && mPath != null) { @@ -171,9 +185,10 @@ public class StorageVolume implements Parcelable { int storageId = in.readInt(); int mtpReserveSpace = in.readInt(); int allowMassStorage = in.readInt(); + long maxFileSize = in.readLong(); return new StorageVolume(path, description, - removable == 1, emulated == 1, - mtpReserveSpace, storageId, allowMassStorage == 1); + removable == 1, emulated == 1, mtpReserveSpace, + storageId, allowMassStorage == 1, maxFileSize); } public StorageVolume[] newArray(int size) { @@ -193,5 +208,6 @@ public class StorageVolume implements Parcelable { parcel.writeInt(mStorageId); parcel.writeInt(mMtpReserveSpace); parcel.writeInt(mAllowMassStorage ? 1 : 0); + parcel.writeLong(mMaxFileSize); } } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 4bc59e4..9c2133f 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -5318,6 +5318,8 @@ <attr name="mtpReserve" format="integer" /> <!-- true if the storage can be shared via USB mass storage --> <attr name="allowMassStorage" format="boolean" /> + <!-- maximum file size for the volume in megabytes, zero or unspecified if it is unbounded --> + <attr name="maxFileSize" format="integer" /> </declare-styleable> <declare-styleable name="SwitchPreference"> diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java index b75b11a..76c8569 100644 --- a/media/java/android/mtp/MtpPropertyGroup.java +++ b/media/java/android/mtp/MtpPropertyGroup.java @@ -330,7 +330,6 @@ class MtpPropertyGroup { } int count = (c == null ? 1 : c.getCount()); - Log.d(TAG, "count: " + count); MtpPropertyList result = new MtpPropertyList(count * mProperties.length, MtpConstants.RESPONSE_OK); diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java index 7932d34..da190a6 100644 --- a/media/java/android/mtp/MtpStorage.java +++ b/media/java/android/mtp/MtpStorage.java @@ -32,6 +32,7 @@ public class MtpStorage { private final String mDescription; private final long mReserveSpace; private final boolean mRemovable; + private final long mMaxFileSize; public MtpStorage(StorageVolume volume) { mStorageId = volume.getStorageId(); @@ -39,6 +40,7 @@ public class MtpStorage { mDescription = volume.getDescription(); mReserveSpace = volume.getMtpReserveSpace(); mRemovable = volume.isRemovable(); + mMaxFileSize = volume.getMaxFileSize(); } /** @@ -98,4 +100,13 @@ public class MtpStorage { public final boolean isRemovable() { return mRemovable; } + + /** + * Returns maximum file size for the storage, or zero if it is unbounded. + * + * @return maximum file size + */ + public long getMaxFileSize() { + return mMaxFileSize; + } } diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index aaf85c3..446b630 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -48,6 +48,7 @@ static jfieldID field_MtpStorage_path; static jfieldID field_MtpStorage_description; static jfieldID field_MtpStorage_reserveSpace; static jfieldID field_MtpStorage_removable; +static jfieldID field_MtpStorage_maxFileSize; static Mutex sMutex; @@ -228,12 +229,14 @@ android_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage) jstring description = (jstring)env->GetObjectField(jstorage, field_MtpStorage_description); jlong reserveSpace = env->GetLongField(jstorage, field_MtpStorage_reserveSpace); jboolean removable = env->GetBooleanField(jstorage, field_MtpStorage_removable); + jlong maxFileSize = env->GetLongField(jstorage, field_MtpStorage_maxFileSize); const char *pathStr = env->GetStringUTFChars(path, NULL); if (pathStr != NULL) { const char *descriptionStr = env->GetStringUTFChars(description, NULL); if (descriptionStr != NULL) { - MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr, reserveSpace, removable); + MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr, + reserveSpace, removable, maxFileSize); thread->addStorage(storage); env->ReleaseStringUTFChars(path, pathStr); env->ReleaseStringUTFChars(description, descriptionStr); @@ -312,6 +315,11 @@ int register_android_mtp_MtpServer(JNIEnv *env) LOGE("Can't find MtpStorage.mRemovable"); return -1; } + field_MtpStorage_maxFileSize = env->GetFieldID(clazz, "mMaxFileSize", "J"); + if (field_MtpStorage_maxFileSize == NULL) { + LOGE("Can't find MtpStorage.mMaxFileSize"); + return -1; + } clazz_MtpStorage = (jclass)env->NewGlobalRef(clazz); clazz = env->FindClass("android/mtp/MtpServer"); diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp index bc04e8c..9085f10 100644 --- a/media/mtp/MtpServer.cpp +++ b/media/mtp/MtpServer.cpp @@ -871,6 +871,14 @@ MtpResponseCode MtpServer::doSendObjectInfo() { // check space first if (mSendObjectFileSize > storage->getFreeSpace()) return MTP_RESPONSE_STORAGE_FULL; + uint64_t maxFileSize = storage->getMaxFileSize(); + // check storage max file size + if (maxFileSize != 0) { + // if mSendObjectFileSize is 0xFFFFFFFF, then all we know is the file size + // is >= 0xFFFFFFFF + if (mSendObjectFileSize > maxFileSize || mSendObjectFileSize == 0xFFFFFFFF) + return MTP_RESPONSE_OBJECT_TOO_LARGE; + } LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID); MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path, diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp index fef8066..941e303 100644 --- a/media/mtp/MtpStorage.cpp +++ b/media/mtp/MtpStorage.cpp @@ -33,11 +33,13 @@ namespace android { MtpStorage::MtpStorage(MtpStorageID id, const char* filePath, - const char* description, uint64_t reserveSpace, bool removable) + const char* description, uint64_t reserveSpace, + bool removable, uint64_t maxFileSize) : mStorageID(id), mFilePath(filePath), mDescription(description), mMaxCapacity(0), + mMaxFileSize(maxFileSize), mReserveSpace(reserveSpace), mRemovable(removable) { diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h index 3e4f40d..e5a2e57 100644 --- a/media/mtp/MtpStorage.h +++ b/media/mtp/MtpStorage.h @@ -31,6 +31,7 @@ private: MtpString mFilePath; MtpString mDescription; uint64_t mMaxCapacity; + uint64_t mMaxFileSize; // amount of free space to leave unallocated uint64_t mReserveSpace; bool mRemovable; @@ -38,7 +39,7 @@ private: public: MtpStorage(MtpStorageID id, const char* filePath, const char* description, uint64_t reserveSpace, - bool removable); + bool removable, uint64_t maxFileSize); virtual ~MtpStorage(); inline MtpStorageID getStorageID() const { return mStorageID; } @@ -50,6 +51,7 @@ public: const char* getDescription() const; inline const char* getPath() const { return (const char *)mFilePath; } inline bool isRemovable() const { return mRemovable; } + inline uint64_t getMaxFileSize() const { return mMaxFileSize; } }; }; // namespace android diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 54e5432..2e54c99 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -1075,18 +1075,22 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC com.android.internal.R.styleable.Storage_mtpReserve, 0); boolean allowMassStorage = a.getBoolean( com.android.internal.R.styleable.Storage_allowMassStorage, false); + // resource parser does not support longs, so XML value is in megabytes + long maxFileSize = a.getInt( + com.android.internal.R.styleable.Storage_maxFileSize, 0) * 1024L * 1024L; Slog.d(TAG, "got storage path: " + path + " description: " + description + " primary: " + primary + " removable: " + removable + " emulated: " + emulated + " mtpReserve: " + mtpReserve + - " allowMassStorage: " + allowMassStorage); + " allowMassStorage: " + allowMassStorage + + " maxFileSize: " + maxFileSize); if (path == null || description == null) { Slog.e(TAG, "path or description is null in readStorageList"); } else { String pathString = path.toString(); StorageVolume volume = new StorageVolume(pathString, description.toString(), removable, emulated, - mtpReserve, allowMassStorage); + mtpReserve, allowMassStorage, maxFileSize); if (primary) { if (mPrimaryVolume == null) { mPrimaryVolume = volume; |