Monitor udev events for the MMC subsystem.

cros-disks previously monitored udev events from the SCSI subsystem and
missed the events from the MMC subsystem, which is associated with some
SD card readers.

BUG=chromium:375368
TEST=Tested the following:
1. `FEATURES=test emerge-$BOARD platform2`
2. Run the following command under a root shell to monitor DeviceAdded
   and DeviceRemoved signal emitted by cros-disks on Link and Blaze:

     dbus-monitor --system --monitor 'interface=org.chromium.CrosDisks'

   A DeviceAdded signal should be emitted when a SD card is inserted.
   A DeviceRemoved signal should be emitted when a SD card is removed.

Change-Id: I50277e2805561ac618f9f7623b582c09a2bf2aff
Reviewed-on: https://chromium-review.googlesource.com/203174
Commit-Queue: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
Reviewed-by: Toni Barzic <tbarzic@chromium.org>
diff --git a/disk_manager.cc b/disk_manager.cc
index 5b03f33..d40ae34 100644
--- a/disk_manager.cc
+++ b/disk_manager.cc
@@ -33,6 +33,7 @@
 namespace {
 
 const char kBlockSubsystem[] = "block";
+const char kMmcSubsystem[] = "mmc";
 const char kScsiSubsystem[] = "scsi";
 const char kScsiDevice[] = "scsi_device";
 const char kUdevAddAction[] = "add";
@@ -59,6 +60,8 @@
   udev_monitor_filter_add_match_subsystem_devtype(udev_monitor_,
                                                   kBlockSubsystem, NULL);
   udev_monitor_filter_add_match_subsystem_devtype(udev_monitor_,
+                                                  kMmcSubsystem, NULL);
+  udev_monitor_filter_add_match_subsystem_devtype(udev_monitor_,
                                                   kScsiSubsystem, kScsiDevice);
   udev_monitor_enable_receiving(udev_monitor_);
   udev_monitor_fd_ = udev_monitor_get_fd(udev_monitor_);
@@ -193,7 +196,7 @@
   }
 }
 
-void DiskManager::ProcessScsiDeviceEvents(
+void DiskManager::ProcessMmcOrScsiDeviceEvents(
     struct udev_device* dev, const char* action, DeviceEventList* events) {
   UdevDevice device(dev);
   if (device.IsMobileBroadbandDevice())
@@ -239,12 +242,14 @@
     return false;
   }
 
-  // udev_monitor_ only monitors block or scsi device changes, so
-  // subsystem is either "block" or "scsi".
+  // |udev_monitor_| only monitors block, mmc, and scsi device changes, so
+  // subsystem is either "block", "mmc", or "scsi".
   if (strcmp(subsystem, kBlockSubsystem) == 0) {
     ProcessBlockDeviceEvents(dev, action, events);
-  } else {  // strcmp(subsystem, kScsiSubsystem) == 0
-    ProcessScsiDeviceEvents(dev, action, events);
+  } else {
+    // strcmp(subsystem, kMmcSubsystem) == 0 ||
+    // strcmp(subsystem, kScsiSubsystem) == 0
+    ProcessMmcOrScsiDeviceEvents(dev, action, events);
   }
 
   udev_device_unref(dev);
diff --git a/disk_manager.h b/disk_manager.h
index 2a85127..70f33e7 100644
--- a/disk_manager.h
+++ b/disk_manager.h
@@ -121,9 +121,11 @@
   void ProcessBlockDeviceEvents(struct udev_device* device, const char *action,
                                 DeviceEventList* events);
 
-  // Determines one or more device/disk events from a udev SCSI device change.
-  void ProcessScsiDeviceEvents(struct udev_device* device, const char *action,
-                               DeviceEventList* events);
+  // Determines one or more device/disk events from a udev MMC or SCSI device
+  // change.
+  void ProcessMmcOrScsiDeviceEvents(struct udev_device* device,
+                                    const char* action,
+                                    DeviceEventList* events);
 
   // If |disk| should be ejected on unmount, add |mount_path| and the device
   // file of |disk| to |devices_to_eject_on_unmount_| and returns true. Returns