Add eventsSupported property to MtpDeviceInfo.

The property provides the set of event code that are supported by
MtpDevice.

BUG=26147375

Change-Id: I54be75e4bb52ddfe9aba8630538ddd32d1a641c8
This commit is contained in:
Daichi Hirono
2016-01-21 19:55:45 +09:00
parent 69c8cc2930
commit 148954a657
11 changed files with 139 additions and 33 deletions

View File

@@ -22632,6 +22632,7 @@ package android.mtp {
}
public class MtpDeviceInfo {
method public final int[] getEventsSupported();
method public final java.lang.String getManufacturer();
method public final java.lang.String getModel();
method public final int[] getOperationsSupported();

View File

@@ -24190,6 +24190,7 @@ package android.mtp {
}
public class MtpDeviceInfo {
method public final int[] getEventsSupported();
method public final java.lang.String getManufacturer();
method public final java.lang.String getModel();
method public final int[] getOperationsSupported();

View File

@@ -22640,6 +22640,7 @@ package android.mtp {
}
public class MtpDeviceInfo {
method public final int[] getEventsSupported();
method public final java.lang.String getManufacturer();
method public final java.lang.String getModel();
method public final int[] getOperationsSupported();

View File

@@ -30,6 +30,7 @@ public class MtpDeviceInfo {
private String mVersion;
private String mSerialNumber;
private int[] mOperationsSupported;
private int[] mEventsSupported;
// only instantiated via JNI
private MtpDeviceInfo() {
@@ -74,9 +75,71 @@ public class MtpDeviceInfo {
/**
* Returns operation code supported by the device.
*
* @return supported operation code
* @return supported operation code. Can be null if device does not provide the property.
* @see MtpConstants#OPERATION_GET_DEVICE_INFO
* @see MtpConstants#OPERATION_OPEN_SESSION
* @see MtpConstants#OPERATION_CLOSE_SESSION
* @see MtpConstants#OPERATION_GET_STORAGE_I_DS
* @see MtpConstants#OPERATION_GET_STORAGE_INFO
* @see MtpConstants#OPERATION_GET_NUM_OBJECTS
* @see MtpConstants#OPERATION_GET_OBJECT_HANDLES
* @see MtpConstants#OPERATION_GET_OBJECT_INFO
* @see MtpConstants#OPERATION_GET_OBJECT
* @see MtpConstants#OPERATION_GET_THUMB
* @see MtpConstants#OPERATION_DELETE_OBJECT
* @see MtpConstants#OPERATION_SEND_OBJECT_INFO
* @see MtpConstants#OPERATION_SEND_OBJECT
* @see MtpConstants#OPERATION_INITIATE_CAPTURE
* @see MtpConstants#OPERATION_FORMAT_STORE
* @see MtpConstants#OPERATION_RESET_DEVICE
* @see MtpConstants#OPERATION_SELF_TEST
* @see MtpConstants#OPERATION_SET_OBJECT_PROTECTION
* @see MtpConstants#OPERATION_POWER_DOWN
* @see MtpConstants#OPERATION_GET_DEVICE_PROP_DESC
* @see MtpConstants#OPERATION_GET_DEVICE_PROP_VALUE
* @see MtpConstants#OPERATION_SET_DEVICE_PROP_VALUE
* @see MtpConstants#OPERATION_RESET_DEVICE_PROP_VALUE
* @see MtpConstants#OPERATION_TERMINATE_OPEN_CAPTURE
* @see MtpConstants#OPERATION_MOVE_OBJECT
* @see MtpConstants#OPERATION_COPY_OBJECT
* @see MtpConstants#OPERATION_GET_PARTIAL_OBJECT
* @see MtpConstants#OPERATION_INITIATE_OPEN_CAPTURE
* @see MtpConstants#OPERATION_GET_OBJECT_PROPS_SUPPORTED
* @see MtpConstants#OPERATION_GET_OBJECT_PROP_DESC
* @see MtpConstants#OPERATION_GET_OBJECT_PROP_VALUE
* @see MtpConstants#OPERATION_SET_OBJECT_PROP_VALUE
* @see MtpConstants#OPERATION_GET_OBJECT_REFERENCES
* @see MtpConstants#OPERATION_SET_OBJECT_REFERENCES
* @see MtpConstants#OPERATION_SKIP
*/
public final @Nullable int[] getOperationsSupported() {
return mOperationsSupported;
}
/**
* Returns event code supported by the device.
*
* @return supported event code. Can be null if device does not provide the property.
* @see MtpConstants#EVENT_UNDEFINED
* @see MtpConstants#EVENT_CANCEL_TRANSACTION
* @see MtpConstants#EVENT_OBJECT_ADDED
* @see MtpConstants#EVENT_OBJECT_REMOVED
* @see MtpConstants#EVENT_STORE_ADDED
* @see MtpConstants#EVENT_STORE_REMOVED
* @see MtpConstants#EVENT_DEVICE_PROP_CHANGED
* @see MtpConstants#EVENT_OBJECT_INFO_CHANGED
* @see MtpConstants#EVENT_DEVICE_INFO_CHANGED
* @see MtpConstants#EVENT_REQUEST_OBJECT_TRANSFER
* @see MtpConstants#EVENT_STORE_FULL
* @see MtpConstants#EVENT_DEVICE_RESET
* @see MtpConstants#EVENT_STORAGE_INFO_CHANGED
* @see MtpConstants#EVENT_CAPTURE_COMPLETE
* @see MtpConstants#EVENT_UNREPORTED_STATUS
* @see MtpConstants#EVENT_OBJECT_PROP_CHANGED
* @see MtpConstants#EVENT_OBJECT_PROP_DESC_CHANGED
* @see MtpConstants#EVENT_OBJECT_REFERENCES_CHANGED
*/
public final @Nullable int[] getEventsSupported() {
return mEventsSupported;
}
}

View File

@@ -25,6 +25,8 @@
#include <unistd.h>
#include <fcntl.h>
#include <memory>
#include "jni.h"
#include "JNIHelp.h"
#include "ScopedPrimitiveArray.h"
@@ -66,6 +68,7 @@ static jfieldID field_deviceInfo_model;
static jfieldID field_deviceInfo_version;
static jfieldID field_deviceInfo_serialNumber;
static jfieldID field_deviceInfo_operationsSupported;
static jfieldID field_deviceInfo_eventsSupported;
// MtpStorageInfo fields
static jfieldID field_storageInfo_storageId;
@@ -216,7 +219,7 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
ALOGD("android_mtp_MtpDevice_get_device_info device is null");
return NULL;
}
MtpDeviceInfo* deviceInfo = device->getDeviceInfo();
std::unique_ptr<MtpDeviceInfo> deviceInfo(device->getDeviceInfo());
if (!deviceInfo) {
ALOGD("android_mtp_MtpDevice_get_device_info deviceInfo is null");
return NULL;
@@ -224,7 +227,6 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
jobject info = env->NewObject(clazz_deviceInfo, constructor_deviceInfo);
if (info == NULL) {
ALOGE("Could not create a MtpDeviceInfo object");
delete deviceInfo;
return NULL;
}
@@ -242,17 +244,35 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz)
env->NewStringUTF(deviceInfo->mSerial));
if (deviceInfo->mOperations) {
const size_t size = deviceInfo->mOperations->size();
const jintArray operations = env->NewIntArray(size);
ScopedLocalRef<jintArray> operations(env, static_cast<jintArray>(env->NewIntArray(size)));
{
ScopedIntArrayRW elements(env, operations);
ScopedIntArrayRW elements(env, operations.get());
if (elements.get() == NULL) {
ALOGE("Could not create operationsSupported element.");
return NULL;
}
for (size_t i = 0; i < size; ++i) {
elements[i] = deviceInfo->mOperations->itemAt(i);
}
env->SetObjectField(info, field_deviceInfo_operationsSupported, operations.get());
}
}
if (deviceInfo->mEvents) {
const size_t size = deviceInfo->mEvents->size();
ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size)));
{
ScopedIntArrayRW elements(env, events.get());
if (elements.get() == NULL) {
ALOGE("Could not create eventsSupported element.");
return NULL;
}
for (size_t i = 0; i < size; ++i) {
elements[i] = deviceInfo->mEvents->itemAt(i);
}
env->SetObjectField(info, field_deviceInfo_eventsSupported, events.get());
}
env->SetObjectField(info, field_deviceInfo_operationsSupported, operations);
}
delete deviceInfo;
return info;
}
@@ -686,6 +706,11 @@ int register_android_mtp_MtpDevice(JNIEnv *env)
ALOGE("Can't find MtpDeviceInfo.mOperationsSupported");
return -1;
}
field_deviceInfo_eventsSupported = env->GetFieldID(clazz, "mEventsSupported", "[I");
if (field_deviceInfo_eventsSupported == NULL) {
ALOGE("Can't find MtpDeviceInfo.mEventsSupported");
return -1;
}
clazz_deviceInfo = (jclass)env->NewGlobalRef(clazz);
clazz = env->FindClass("android/mtp/MtpStorageInfo");

View File

@@ -16,19 +16,23 @@
package com.android.mtp;
import android.annotation.Nullable;
class MtpDeviceRecord {
public final int deviceId;
public final String name;
public final boolean opened;
public final MtpRoot[] roots;
public final int[] operationsSupported;
public final @Nullable int[] operationsSupported;
public final @Nullable int[] eventsSupported;
MtpDeviceRecord(
int deviceId, String name, boolean opened, MtpRoot[] roots, int[] operationsSupported) {
MtpDeviceRecord(int deviceId, String name, boolean opened, MtpRoot[] roots,
@Nullable int[] operationsSupported, @Nullable int[] eventsSupported) {
this.deviceId = deviceId;
this.name = name;
this.opened = opened;
this.roots = roots;
this.operationsSupported = operationsSupported;
this.eventsSupported = eventsSupported;
}
}

View File

@@ -129,6 +129,7 @@ class MtpManager {
final String name = device.getProductName();
MtpRoot[] roots;
int[] operationsSupported = null;
int[] eventsSupported = null;
if (opened) {
try {
roots = getRoots(device.getDeviceId());
@@ -142,16 +143,14 @@ class MtpManager {
final MtpDeviceInfo info = mtpDevice.getDeviceInfo();
if (info != null) {
operationsSupported = mtpDevice.getDeviceInfo().getOperationsSupported();
}
if (operationsSupported == null) {
operationsSupported = new int[0];
eventsSupported = mtpDevice.getDeviceInfo().getEventsSupported();
}
} else {
roots = new MtpRoot[0];
operationsSupported = new int[0];
}
devices.add(new MtpDeviceRecord(
device.getDeviceId(), name, opened, roots, operationsSupported));
device.getDeviceId(), name, opened, roots, operationsSupported,
eventsSupported));
}
return devices.toArray(new MtpDeviceRecord[devices.size()]);
}

View File

@@ -77,7 +77,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
public void testPutSingleStorageDocuments() throws Exception {
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
mDatabase.getMapper().startAddingDocuments("1");
@@ -425,9 +425,9 @@ public class MtpDatabaseTest extends AndroidTestCase {
};
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], null, null));
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
mDatabase.getMapper().startAddingDocuments("1");
@@ -562,7 +562,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
mDatabase.getMapper().startAddingDocuments("1");
@@ -640,7 +640,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
public void testReplaceExistingRoots() {
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
// The client code should be able to replace existing rows with new information.
@@ -691,7 +691,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
// Add one.
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
mDatabase.getMapper().startAddingDocuments("1");
@@ -745,7 +745,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
// Add device document.
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
// It the device does not have storages, it shows a device root.
@@ -895,7 +895,7 @@ public class MtpDatabaseTest extends AndroidTestCase {
public void testGetDocumentIdForDevice() {
mDatabase.getMapper().startAddingDocuments(null);
mDatabase.getMapper().putDeviceDocument(
new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], new int[0]));
new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], null, null));
mDatabase.getMapper().stopAddingDocuments(null);
assertEquals("1", mDatabase.getDocumentIdForDevice(100));
}

View File

@@ -69,7 +69,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
2048 /* total space */,
"" /* no volume identifier */)
},
new int[0]));
null,
null));
mProvider.openDevice(0);
mResolver.waitForNotification(ROOTS_URI, 1);
@@ -109,7 +110,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
2048 /* total space */,
"" /* no volume identifier */)
},
new int[0]));
null,
null));
mProvider.openDevice(0);
mResolver.waitForNotification(ROOTS_URI, 1);
}
@@ -130,7 +132,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
2048 /* total space */,
"" /* no volume identifier */)
},
new int[0]));
null,
null));
mMtpManager.addValidDevice(new MtpDeviceRecord(
1,
"Device",
@@ -145,7 +148,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
4096 /* total space */,
"Identifier B" /* no volume identifier */)
},
new int[0]));
null,
null));
{
mProvider.openDevice(0);
@@ -180,7 +184,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
public void testQueryRoots_error() throws Exception {
setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
mMtpManager.addValidDevice(new MtpDeviceRecord(
0, "Device A", false /* unopened */, new MtpRoot[0], new int[0]));
0, "Device A", false /* unopened */, new MtpRoot[0], null, null));
mMtpManager.addValidDevice(new MtpDeviceRecord(
1,
"Device",
@@ -195,7 +199,8 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
4096 /* total space */,
"Identifier B" /* no volume identifier */)
},
new int[0]));
null,
null));
{
mProvider.openDevice(0);
mProvider.openDevice(1);
@@ -438,7 +443,7 @@ public class MtpDocumentsProviderTest extends AndroidTestCase {
throws InterruptedException, TimeoutException, IOException {
final int changeCount = mResolver.getChangeCount(ROOTS_URI);
mMtpManager.addValidDevice(
new MtpDeviceRecord(deviceId, "Device", false /* unopened */, roots, new int[0]));
new MtpDeviceRecord(deviceId, "Device", false /* unopened */, roots, null, null));
mProvider.openDevice(deviceId);
mResolver.waitForNotification(ROOTS_URI, changeCount + 1);
return getStrings(mProvider.queryRoots(strings(DocumentsContract.Root.COLUMN_ROOT_ID)));

View File

@@ -87,6 +87,13 @@ public class MtpManagerTest extends InstrumentationTestCase {
getInstrumentation().show(Arrays.toString(records[0].operationsSupported));
}
public void testEventsSupported() {
final MtpDeviceRecord[] records = mManager.getDevices();
assertEquals(1, records.length);
assertNotNull(records[0].eventsSupported);
getInstrumentation().show(Arrays.toString(records[0].eventsSupported));
}
public void testEventObjectAdded() throws Exception {
while (true) {
getInstrumentation().show("Please take a photo by using connected MTP device.");

View File

@@ -76,7 +76,7 @@ public class TestMtpManager extends MtpManager {
result[i] = device;
} else {
result[i] = new MtpDeviceRecord(
device.deviceId, device.name, device.opened, new MtpRoot[0], new int[0]);
device.deviceId, device.name, device.opened, new MtpRoot[0], null, null);
}
}
return result;
@@ -90,7 +90,7 @@ public class TestMtpManager extends MtpManager {
}
mDevices.put(
deviceId,
new MtpDeviceRecord(device.deviceId, device.name, true, device.roots, new int[0]));
new MtpDeviceRecord(device.deviceId, device.name, true, device.roots, null, null));
}
@Override
@@ -101,7 +101,7 @@ public class TestMtpManager extends MtpManager {
}
mDevices.put(
deviceId,
new MtpDeviceRecord(device.deviceId, device.name, false, device.roots, new int[0]));
new MtpDeviceRecord(device.deviceId, device.name, false, device.roots, null, null));
}
@Override