use of android.mtp.MtpObjectInfo in project android_frameworks_base by ResurrectionRemix.
the class MtpDocumentsProvider method createDocument.
@Override
public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException {
if (DEBUG) {
Log.d(TAG, "createDocument: " + displayName);
}
final Identifier parentId;
final MtpDeviceRecord record;
final ParcelFileDescriptor[] pipe;
try {
parentId = mDatabase.createIdentifier(parentDocumentId);
openDevice(parentId.mDeviceId);
record = getDeviceToolkit(parentId.mDeviceId).mDeviceRecord;
if (!MtpDeviceRecord.isWritingSupported(record.operationsSupported)) {
throw new UnsupportedOperationException("Writing operation is not supported by the device.");
}
final int parentObjectHandle;
final int storageId;
switch(parentId.mDocumentType) {
case MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE:
final String[] storageDocumentIds = mDatabase.getStorageDocumentIds(parentId.mDocumentId);
if (storageDocumentIds.length == 1) {
final String newDocumentId = createDocument(storageDocumentIds[0], mimeType, displayName);
notifyChildDocumentsChange(parentDocumentId);
return newDocumentId;
} else {
throw new UnsupportedOperationException("Cannot create a file under the device.");
}
case MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE:
storageId = parentId.mStorageId;
parentObjectHandle = -1;
break;
case MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT:
storageId = parentId.mStorageId;
parentObjectHandle = parentId.mObjectHandle;
break;
default:
throw new IllegalArgumentException("Unexpected document type.");
}
pipe = ParcelFileDescriptor.createReliablePipe();
int objectHandle = -1;
MtpObjectInfo info = null;
try {
// 0 bytes for a new document.
pipe[0].close();
final int formatCode = Document.MIME_TYPE_DIR.equals(mimeType) ? MtpConstants.FORMAT_ASSOCIATION : MediaFile.getFormatCode(displayName, mimeType);
info = new MtpObjectInfo.Builder().setStorageId(storageId).setParent(parentObjectHandle).setFormat(formatCode).setName(displayName).build();
final String[] parts = FileUtils.splitFileName(mimeType, displayName);
final String baseName = parts[0];
final String extension = parts[1];
for (int i = 0; i <= 32; i++) {
final MtpObjectInfo infoUniqueName;
if (i == 0) {
infoUniqueName = info;
} else {
String suffixedName = baseName + " (" + i + " )";
if (!extension.isEmpty()) {
suffixedName += "." + extension;
}
infoUniqueName = new MtpObjectInfo.Builder(info).setName(suffixedName).build();
}
try {
objectHandle = mMtpManager.createDocument(parentId.mDeviceId, infoUniqueName, pipe[1]);
break;
} catch (SendObjectInfoFailure exp) {
// This can be caused when we have an existing file with the same name.
continue;
}
}
} finally {
pipe[1].close();
}
if (objectHandle == -1) {
throw new IllegalArgumentException("The file name \"" + displayName + "\" is conflicted with existing files " + "and the provider failed to find unique name.");
}
final MtpObjectInfo infoWithHandle = new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
final String documentId = mDatabase.putNewDocument(parentId.mDeviceId, parentDocumentId, record.operationsSupported, infoWithHandle, 0l);
getDocumentLoader(parentId).cancelTask(parentId);
notifyChildDocumentsChange(parentDocumentId);
return documentId;
} catch (FileNotFoundException | RuntimeException error) {
Log.e(TAG, "createDocument", error);
throw error;
} catch (IOException error) {
Log.e(TAG, "createDocument", error);
throw new IllegalStateException(error);
}
}
use of android.mtp.MtpObjectInfo in project android_frameworks_base by ResurrectionRemix.
the class MtpDocumentsProviderTest method testQueryDocument_directory.
public void testQueryDocument_directory() throws IOException, InterruptedException, TimeoutException {
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
setupDocuments(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, "1", new MtpObjectInfo[] { new MtpObjectInfo.Builder().setObjectHandle(2).setStorageId(1).setFormat(MtpConstants.FORMAT_ASSOCIATION).setName("directory").setDateModified(1422716400000L).build() });
final Cursor cursor = mProvider.queryDocument("3", null);
assertEquals(1, cursor.getCount());
cursor.moveToNext();
assertEquals("3", cursor.getString(0));
assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, cursor.getString(1));
assertEquals("directory", cursor.getString(2));
assertEquals(1422716400000L, cursor.getLong(3));
assertEquals(DocumentsContract.Document.FLAG_SUPPORTS_DELETE | DocumentsContract.Document.FLAG_DIR_SUPPORTS_CREATE, cursor.getInt(4));
assertEquals(0, cursor.getInt(5));
}
use of android.mtp.MtpObjectInfo in project android_frameworks_base by ResurrectionRemix.
the class TestMtpManager method createDocument.
@Override
int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source) throws IOException {
Assert.assertNotSame(0, objectInfo.getStorageId());
Assert.assertNotSame(-1, objectInfo.getStorageId());
Assert.assertNotSame(0, objectInfo.getParent());
final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
if (mObjectInfos.containsKey(key)) {
throw new IOException();
}
final MtpObjectInfo newInfo = new MtpObjectInfo.Builder(objectInfo).setObjectHandle(CREATED_DOCUMENT_HANDLE).build();
mObjectInfos.put(key, newInfo);
if (objectInfo.getFormat() != 0x3001) {
try (final ParcelFileDescriptor.AutoCloseInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(source)) {
final byte[] buffer = new byte[objectInfo.getCompressedSize()];
if (inputStream.read(buffer, 0, objectInfo.getCompressedSize()) != objectInfo.getCompressedSize()) {
throw new IOException();
}
mImportFileBytes.put(pack(deviceId, CREATED_DOCUMENT_HANDLE), buffer);
}
}
return CREATED_DOCUMENT_HANDLE;
}
use of android.mtp.MtpObjectInfo in project android_frameworks_base by DirtyUnicorns.
the class MtpDocumentsProvider method createDocument.
@Override
public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException {
if (DEBUG) {
Log.d(TAG, "createDocument: " + displayName);
}
final Identifier parentId;
final MtpDeviceRecord record;
final ParcelFileDescriptor[] pipe;
try {
parentId = mDatabase.createIdentifier(parentDocumentId);
openDevice(parentId.mDeviceId);
record = getDeviceToolkit(parentId.mDeviceId).mDeviceRecord;
if (!MtpDeviceRecord.isWritingSupported(record.operationsSupported)) {
throw new UnsupportedOperationException("Writing operation is not supported by the device.");
}
final int parentObjectHandle;
final int storageId;
switch(parentId.mDocumentType) {
case MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE:
final String[] storageDocumentIds = mDatabase.getStorageDocumentIds(parentId.mDocumentId);
if (storageDocumentIds.length == 1) {
final String newDocumentId = createDocument(storageDocumentIds[0], mimeType, displayName);
notifyChildDocumentsChange(parentDocumentId);
return newDocumentId;
} else {
throw new UnsupportedOperationException("Cannot create a file under the device.");
}
case MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE:
storageId = parentId.mStorageId;
parentObjectHandle = -1;
break;
case MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT:
storageId = parentId.mStorageId;
parentObjectHandle = parentId.mObjectHandle;
break;
default:
throw new IllegalArgumentException("Unexpected document type.");
}
pipe = ParcelFileDescriptor.createReliablePipe();
int objectHandle = -1;
MtpObjectInfo info = null;
try {
// 0 bytes for a new document.
pipe[0].close();
final int formatCode = Document.MIME_TYPE_DIR.equals(mimeType) ? MtpConstants.FORMAT_ASSOCIATION : MediaFile.getFormatCode(displayName, mimeType);
info = new MtpObjectInfo.Builder().setStorageId(storageId).setParent(parentObjectHandle).setFormat(formatCode).setName(displayName).build();
final String[] parts = FileUtils.splitFileName(mimeType, displayName);
final String baseName = parts[0];
final String extension = parts[1];
for (int i = 0; i <= 32; i++) {
final MtpObjectInfo infoUniqueName;
if (i == 0) {
infoUniqueName = info;
} else {
String suffixedName = baseName + " (" + i + " )";
if (!extension.isEmpty()) {
suffixedName += "." + extension;
}
infoUniqueName = new MtpObjectInfo.Builder(info).setName(suffixedName).build();
}
try {
objectHandle = mMtpManager.createDocument(parentId.mDeviceId, infoUniqueName, pipe[1]);
break;
} catch (SendObjectInfoFailure exp) {
// This can be caused when we have an existing file with the same name.
continue;
}
}
} finally {
pipe[1].close();
}
if (objectHandle == -1) {
throw new IllegalArgumentException("The file name \"" + displayName + "\" is conflicted with existing files " + "and the provider failed to find unique name.");
}
final MtpObjectInfo infoWithHandle = new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
final String documentId = mDatabase.putNewDocument(parentId.mDeviceId, parentDocumentId, record.operationsSupported, infoWithHandle, 0l);
getDocumentLoader(parentId).cancelTask(parentId);
notifyChildDocumentsChange(parentDocumentId);
return documentId;
} catch (FileNotFoundException | RuntimeException error) {
Log.e(TAG, "createDocument", error);
throw error;
} catch (IOException error) {
Log.e(TAG, "createDocument", error);
throw new IllegalStateException(error);
}
}
use of android.mtp.MtpObjectInfo in project android_frameworks_base by DirtyUnicorns.
the class MtpClient method getObjectList.
/**
* Retrieves a list of {@link android.mtp.MtpObjectInfo} for all objects
* on the MTP or PTP device with the given USB device name and given storage ID
* and/or object handle.
* If the object handle is zero, then all objects in the root of the storage unit
* will be returned. Otherwise, all immediate children of the object will be returned.
* If the storage ID is also zero, then all objects on all storage units will be returned.
*
* @param deviceName the name of the USB device
* @param storageId the ID of the storage unit to query, or zero for all
* @param objectHandle the handle of the parent object to query, or zero for the storage root
* @return the list of MtpObjectInfo
*/
public List<MtpObjectInfo> getObjectList(String deviceName, int storageId, int objectHandle) {
MtpDevice device = getDevice(deviceName);
if (device == null) {
return null;
}
if (objectHandle == 0) {
// all objects in root of storage
objectHandle = 0xFFFFFFFF;
}
int[] handles = device.getObjectHandles(storageId, 0, objectHandle);
if (handles == null) {
return null;
}
int length = handles.length;
ArrayList<MtpObjectInfo> objectList = new ArrayList<MtpObjectInfo>(length);
for (int i = 0; i < length; i++) {
MtpObjectInfo info = device.getObjectInfo(handles[i]);
if (info == null) {
Log.w(TAG, "getObjectInfo failed");
} else {
objectList.add(info);
}
}
return objectList;
}
Aggregations