44
44
#if defined(HAVE_GUDEV )
45
45
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
46
46
#include <gudev/gudev.h>
47
- #endif
47
+
48
+ #if defined(WITH_LIBMTP )
49
+ #include <libmtp.h>
50
+
51
+ /* bug flags set for Android devices */
52
+ #define DEVICE_FLAG_UNLOAD_DRIVER 0x00000002
53
+ #define DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST 0x00000004
54
+ #define DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST 0x00000100
55
+ #define DEVICE_FLAG_BROKEN_SEND_OBJECT_PROPLIST 0x00008000
56
+ #define DEVICE_FLAG_LONG_TIMEOUT 0x08000000
57
+ #define DEVICE_FLAG_FORCE_RESET_ON_CLOSE 0x10000000
58
+
59
+ /* Nexus/Pixel (MTP) (1831:4ee1) masks off BROKEN_MTPGETOBJPROPLIST */
60
+ #define DEVICE_FLAGS_ANDROID_BUGS (\
61
+ /*DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST |*/ \
62
+ DEVICE_FLAG_BROKEN_SET_OBJECT_PROPLIST | \
63
+ DEVICE_FLAG_BROKEN_SEND_OBJECT_PROPLIST | \
64
+ DEVICE_FLAG_UNLOAD_DRIVER | \
65
+ DEVICE_FLAG_LONG_TIMEOUT | \
66
+ DEVICE_FLAG_FORCE_RESET_ON_CLOSE)
67
+
68
+ #endif /* WITH_LIBMTP */
69
+ #endif /* HAVE_GUDEV */
48
70
49
71
#include "rb-removable-media-manager.h"
50
72
#include "rb-library-source.h"
@@ -917,6 +939,21 @@ rb_removable_media_manager_get_gudev_device (RBRemovableMediaManager *manager, G
917
939
#endif
918
940
}
919
941
942
+ #if defined(HAVE_GUDEV )
943
+ static int
944
+ get_property_as_int (GUdevDevice * device , const char * property , int base )
945
+ {
946
+ const char * strvalue ;
947
+
948
+ strvalue = g_udev_device_get_property (device , property );
949
+ if (strvalue == NULL ) {
950
+ return 0 ;
951
+ }
952
+
953
+ return strtol (strvalue , NULL , base );
954
+ }
955
+ #endif
956
+
920
957
/**
921
958
* rb_removable_media_manager_device_is_android:
922
959
* @manager: the #RBRemovableMediaManager
@@ -927,50 +964,58 @@ rb_removable_media_manager_get_gudev_device (RBRemovableMediaManager *manager, G
927
964
* Return value: %TRUE if the device appears to be Android-based
928
965
*/
929
966
gboolean
930
- rb_removable_media_manager_device_is_android (RBRemovableMediaManager * manager , GObject * device )
967
+ rb_removable_media_manager_device_is_android (RBRemovableMediaManager * manager , GObject * gdevice )
931
968
{
932
- #if defined(HAVE_GUDEV )
933
- gboolean match ;
934
- const char * model ;
935
- const char * vendor ;
969
+ #if !defined(HAVE_GUDEV )
970
+ return TRUE;
971
+ #else
972
+ GUdevDevice * device = G_UDEV_DEVICE (gdevice );
973
+ #if defined(WITH_LIBMTP )
974
+ LIBMTP_device_entry_t * device_list ;
975
+ int numdevs ;
936
976
int i ;
977
+ #endif
978
+ int vendor ;
979
+ int model ;
937
980
938
- const char * androids [] = {
939
- "Android" ,
940
- "Nexus" ,
941
- "Pixel" ,
942
- "Nexus_5X"
943
- };
944
- const char * android_vendors [] = {
945
- "motorola" ,
946
- "OnePlus" ,
947
- "Google" ,
948
- "bq" ,
949
- "HMD_Global" ,
950
- "LENOVO" ,
951
- "asus" ,
952
- };
981
+ if (g_strcmp0 (g_udev_device_get_subsystem (device ), "usb" ) != 0 ) {
982
+ rb_debug ("device %s is not a USB device" , g_udev_device_get_name (device ));
983
+ return FALSE;
984
+ }
953
985
954
- match = FALSE;
986
+ /* check that it's not an iPhone or iPod Touch */
987
+ if (g_udev_device_get_property_as_boolean (device , "USBMUX_SUPPORTED" )) {
988
+ rb_debug ("device %s is supported through AFC, ignore" , g_udev_device_get_name (device ));
989
+ return FALSE;
990
+ }
955
991
956
- model = g_udev_device_get_property (G_UDEV_DEVICE (device ), "ID_MODEL" );
957
- if (model != NULL ) {
958
- for (i = 0 ; i < G_N_ELEMENTS (androids ); i ++ ) {
959
- if (strstr (model , androids [i ]))
960
- match = TRUE;
961
- }
992
+ if (g_udev_device_has_property (device , "ID_MTP_DEVICE" ) == FALSE) {
993
+ rb_debug ("device %s does not support mtp, ignore" , g_udev_device_get_name (device ));
994
+ return FALSE;
962
995
}
963
996
964
- vendor = g_udev_device_get_property (G_UDEV_DEVICE (device ), "ID_VENDOR" );
965
- if (vendor != NULL ) {
966
- for (i = 0 ; i < G_N_ELEMENTS (android_vendors ); i ++ ) {
967
- if (strstr (vendor , android_vendors [i ]))
968
- match = TRUE;
997
+ vendor = get_property_as_int (device , "ID_VENDOR_ID" , 16 );
998
+ model = get_property_as_int (device , "ID_MODEL_ID" , 16 );
999
+ #if defined(WITH_LIBMTP )
1000
+
1001
+ rb_debug ("matching device %x:%x against libmtp device list" , vendor , model );
1002
+ LIBMTP_Get_Supported_Devices_List (& device_list , & numdevs );
1003
+ for (i = 0 ; i < numdevs ; i ++ ) {
1004
+ if (device_list [i ].vendor_id == vendor &&
1005
+ device_list [i ].product_id == model ) {
1006
+ rb_debug ("matched libmtp device vendor %s product %s" , device_list [i ].vendor , device_list [i ].product );
1007
+ if ((device_list [i ].device_flags & DEVICE_FLAGS_ANDROID_BUGS ) != DEVICE_FLAGS_ANDROID_BUGS ) {
1008
+ rb_debug ("device doesn't have all android bug flags set" );
1009
+ return FALSE;
1010
+ } else {
1011
+ rb_debug ("device has android bug flags set" );
1012
+ return TRUE;
1013
+ }
969
1014
}
970
1015
}
971
-
972
- return match ;
973
- #else
974
- return FALSE;
1016
+ #endif
1017
+ rb_debug ("unable to match device %x:%x against device list, assuming android" , vendor , model );
1018
+ return TRUE;
975
1019
#endif
976
1020
}
1021
+
0 commit comments