// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// StorageMonitorLinux implementation.

#include "components/storage_monitor/storage_monitor_linux.h"

#include <mntent.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>

#include <limits>
#include <list>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/storage_monitor/media_storage_util.h"
#include "components/storage_monitor/removable_device_constants.h"
#include "components/storage_monitor/storage_info.h"
#include "components/storage_monitor/udev_util_linux.h"
#include "device/udev_linux/scoped_udev.h"

namespace storage_monitor {

using MountPointDeviceMap = MtabWatcherLinux::MountPointDeviceMap;

namespace {

// udev device property constants.
const char kBlockSubsystemKey[] = "block";
const char kDiskDeviceTypeKey[] = "disk";
const char kFsUUID[] = "ID_FS_UUID";
const char kLabel[] = "ID_FS_LABEL";
const char kModel[] = "ID_MODEL";
const char kModelID[] = "ID_MODEL_ID";
const char kRemovableSysAttr[] = "removable";
const char kSerialShort[] = "ID_SERIAL_SHORT";
const char kSizeSysAttr[] = "size";
const char kVendor[] = "ID_VENDOR";
const char kVendorID[] = "ID_VENDOR_ID";

// Construct a device id using label or manufacturer (vendor and model) details.
std::string MakeDeviceUniqueId(struct udev_device* device) {
  std::string uuid = device::UdevDeviceGetPropertyValue(device, kFsUUID);
  if (!uuid.empty())
    return kFSUniqueIdPrefix + uuid;

  // If one of the vendor, model, serial information is missing, its value
  // in the string is empty.
  // Format: VendorModelSerial:VendorInfo:ModelInfo:SerialShortInfo
  // E.g.: VendorModelSerial:Kn:DataTravel_12.10:8000000000006CB02CDB
  std::string vendor = device::UdevDeviceGetPropertyValue(device, kVendorID);
  std::string model = device::UdevDeviceGetPropertyValue(device, kModelID);
  std::string serial_short =
      device::UdevDeviceGetPropertyValue(device, kSerialShort);
  if (vendor.empty() && model.empty() && serial_short.empty())
    return std::string();

  return kVendorModelSerialPrefix + vendor + ":" + model + ":" + serial_short;
}

// Records GetDeviceInfo result on destruction, to see how often we fail to get
// device details.
class ScopedGetDeviceInfoResultRecorder {
 public:
  ScopedGetDeviceInfoResultRecorder() : result_(false) {}
  ~ScopedGetDeviceInfoResultRecorder() {
    UMA_HISTOGRAM_BOOLEAN("MediaDeviceNotification.UdevRequestSuccess",
                          result_);
  }

  void set_result(bool result) {
    result_ = result;
  }

 private:
  bool result_;

  DISALLOW_COPY_AND_ASSIGN(ScopedGetDeviceInfoResultRecorder);
};

// Returns the storage partition size of the device specified by |device_path|.
// If the requested information is unavailable, returns 0.
uint64_t GetDeviceStorageSize(const base::FilePath& device_path,
                              struct udev_device* device) {
  // sysfs provides the device size in units of 512-byte blocks.
  const std::string partition_size =
      device::UdevDeviceGetSysattrValue(device, kSizeSysAttr);

  uint64_t total_size_in_bytes = 0;
  if (!base::StringToUint64(partition_size, &total_size_in_bytes))
    return 0;
  return (total_size_in_bytes <= std::numeric_limits<uint64_t>::max() / 512)
             ? total_size_in_bytes * 512
             : 0;
}

// Gets the device information using udev library.
std::unique_ptr<StorageInfo> GetDeviceInfo(const base::FilePath& device_path,
                                           const base::FilePath& mount_point) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);
  DCHECK(!device_path.empty());

  std::unique_ptr<StorageInfo> storage_info;

  ScopedGetDeviceInfoResultRecorder results_recorder;

  device::ScopedUdevPtr udev_obj(device::udev_new());
  if (!udev_obj.get())
    return storage_info;

  struct stat device_stat;
  if (stat(device_path.value().c_str(), &device_stat) < 0)
    return storage_info;

  char device_type;
  if (S_ISCHR(device_stat.st_mode))
    device_type = 'c';
  else if (S_ISBLK(device_stat.st_mode))
    device_type = 'b';
  else
    return storage_info;  // Not a supported type.

  device::ScopedUdevDevicePtr device(
      device::udev_device_new_from_devnum(udev_obj.get(), device_type,
                                          device_stat.st_rdev));
  if (!device.get())
    return storage_info;

  base::string16 volume_label = base::UTF8ToUTF16(
      device::UdevDeviceGetPropertyValue(device.get(), kLabel));
  base::string16 vendor_name = base::UTF8ToUTF16(
      device::UdevDeviceGetPropertyValue(device.get(), kVendor));
  base::string16 model_name = base::UTF8ToUTF16(
      device::UdevDeviceGetPropertyValue(device.get(), kModel));

  std::string unique_id = MakeDeviceUniqueId(device.get());
  const char* value =
      device::udev_device_get_sysattr_value(device.get(), kRemovableSysAttr);
  if (!value) {
    // |parent_device| is owned by |device| and does not need to be cleaned
    // up.
    struct udev_device* parent_device =
        device::udev_device_get_parent_with_subsystem_devtype(
            device.get(),
            kBlockSubsystemKey,
            kDiskDeviceTypeKey);
    value = device::udev_device_get_sysattr_value(parent_device,
                                                  kRemovableSysAttr);
  }
  const bool is_removable = (value && atoi(value) == 1);

  StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE;
  if (is_removable) {
    type = MediaStorageUtil::HasDcim(mount_point)
               ? StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM
               : StorageInfo::REMOVABLE_MASS_STORAGE_NO_DCIM;
  }

  results_recorder.set_result(true);

  storage_info = std::make_unique<StorageInfo>(
      StorageInfo::MakeDeviceId(type, unique_id), mount_point.value(),
      volume_label, vendor_name, model_name,
      GetDeviceStorageSize(device_path, device.get()));
  return storage_info;
}

// Runs |callback| with the |new_mtab| on |storage_monitor_task_runner|.
void BounceMtabUpdateToStorageMonitorTaskRunner(
    scoped_refptr<base::SequencedTaskRunner> storage_monitor_task_runner,
    const MtabWatcherLinux::UpdateMtabCallback& callback,
    const MtabWatcherLinux::MountPointDeviceMap& new_mtab) {
  storage_monitor_task_runner->PostTask(FROM_HERE,
                                        base::BindOnce(callback, new_mtab));
}

MtabWatcherLinux* CreateMtabWatcherLinuxOnMtabWatcherTaskRunner(
    const base::FilePath& mtab_path,
    scoped_refptr<base::SequencedTaskRunner> storage_monitor_task_runner,
    const MtabWatcherLinux::UpdateMtabCallback& callback) {
  // Owned by caller.
  return new MtabWatcherLinux(
      mtab_path, base::Bind(&BounceMtabUpdateToStorageMonitorTaskRunner,
                            storage_monitor_task_runner, callback));
}

StorageMonitor::EjectStatus EjectPathOnBlockingTaskRunner(
    const base::FilePath& path,
    const base::FilePath& device) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  // Note: Linux LSB says umount should exist in /bin.
  static const char kUmountBinary[] = "/bin/umount";
  std::vector<std::string> command;
  command.push_back(kUmountBinary);
  command.push_back(path.value());

  base::LaunchOptions options;
  base::Process process = base::LaunchProcess(command, options);
  if (!process.IsValid())
    return StorageMonitor::EJECT_FAILURE;

  int exit_code = -1;
  if (!process.WaitForExitWithTimeout(base::TimeDelta::FromMilliseconds(3000),
                                      &exit_code)) {
    process.Terminate(-1, false);
    base::EnsureProcessTerminated(std::move(process));
    return StorageMonitor::EJECT_FAILURE;
  }

  // TODO(gbillock): Make sure this is found in documentation
  // somewhere. Experimentally it seems to hold that exit code
  // 1 means device is in use.
  if (exit_code == 1)
    return StorageMonitor::EJECT_IN_USE;
  if (exit_code != 0)
    return StorageMonitor::EJECT_FAILURE;

  return StorageMonitor::EJECT_OK;
}

}  // namespace

StorageMonitorLinux::StorageMonitorLinux(const base::FilePath& path)
    : mtab_path_(path),
      get_device_info_callback_(base::Bind(&GetDeviceInfo)),
      mtab_watcher_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}

StorageMonitorLinux::~StorageMonitorLinux() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  mtab_watcher_task_runner_->DeleteSoon(FROM_HERE, mtab_watcher_.release());
}

void StorageMonitorLinux::Init() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!mtab_path_.empty());

  base::PostTaskAndReplyWithResult(
      mtab_watcher_task_runner_.get(), FROM_HERE,
      base::Bind(&CreateMtabWatcherLinuxOnMtabWatcherTaskRunner, mtab_path_,
                 base::SequencedTaskRunnerHandle::Get(),
                 base::Bind(&StorageMonitorLinux::UpdateMtab,
                            weak_ptr_factory_.GetWeakPtr())),
      base::Bind(&StorageMonitorLinux::OnMtabWatcherCreated,
                 weak_ptr_factory_.GetWeakPtr()));
}

bool StorageMonitorLinux::GetStorageInfoForPath(
    const base::FilePath& path,
    StorageInfo* device_info) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(device_info);

  if (!path.IsAbsolute())
    return false;

  base::FilePath current = path;
  while (!base::Contains(mount_info_map_, current) &&
         current != current.DirName())
    current = current.DirName();

  auto mount_info = mount_info_map_.find(current);
  if (mount_info == mount_info_map_.end())
    return false;
  *device_info = mount_info->second.storage_info;
  return true;
}

void StorageMonitorLinux::SetGetDeviceInfoCallbackForTest(
    const GetDeviceInfoCallback& get_device_info_callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  get_device_info_callback_ = get_device_info_callback;
}

void StorageMonitorLinux::EjectDevice(
    const std::string& device_id,
    base::Callback<void(EjectStatus)> callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  StorageInfo::Type type;
  if (!StorageInfo::CrackDeviceId(device_id, &type, nullptr)) {
    callback.Run(EJECT_FAILURE);
    return;
  }

  DCHECK_NE(type, StorageInfo::MTP_OR_PTP);

  // Find the mount point for the given device ID.
  base::FilePath path;
  base::FilePath device;
  for (auto mount_info = mount_info_map_.begin();
       mount_info != mount_info_map_.end(); ++mount_info) {
    if (mount_info->second.storage_info.device_id() == device_id) {
      path = mount_info->first;
      device = mount_info->second.mount_device;
      mount_info_map_.erase(mount_info);
      break;
    }
  }

  if (path.empty()) {
    callback.Run(EJECT_NO_SUCH_DEVICE);
    return;
  }

  receiver()->ProcessDetach(device_id);

  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::Bind(&EjectPathOnBlockingTaskRunner, path, device), callback);
}

void StorageMonitorLinux::OnMtabWatcherCreated(MtabWatcherLinux* watcher) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  mtab_watcher_.reset(watcher);
}

void StorageMonitorLinux::UpdateMtab(const MountPointDeviceMap& new_mtab) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Check existing mtab entries for unaccounted mount points.
  // These mount points must have been removed in the new mtab.
  std::list<base::FilePath> mount_points_to_erase;
  std::list<base::FilePath> multiple_mounted_devices_needing_reattachment;
  for (MountMap::const_iterator old_iter = mount_info_map_.begin();
       old_iter != mount_info_map_.end(); ++old_iter) {
    const base::FilePath& mount_point = old_iter->first;
    const base::FilePath& mount_device = old_iter->second.mount_device;
    auto new_iter = new_mtab.find(mount_point);
    // |mount_point| not in |new_mtab| or |mount_device| is no longer mounted at
    // |mount_point|.
    if (new_iter == new_mtab.end() || (new_iter->second != mount_device)) {
      auto priority = mount_priority_map_.find(mount_device);
      DCHECK(priority != mount_priority_map_.end());
      ReferencedMountPoint::const_iterator has_priority =
          priority->second.find(mount_point);
      if (StorageInfo::IsRemovableDevice(
              old_iter->second.storage_info.device_id())) {
        DCHECK(has_priority != priority->second.end());
        if (has_priority->second) {
          receiver()->ProcessDetach(old_iter->second.storage_info.device_id());
        }
        if (priority->second.size() > 1)
          multiple_mounted_devices_needing_reattachment.push_back(mount_device);
      }
      priority->second.erase(mount_point);
      if (priority->second.empty())
        mount_priority_map_.erase(mount_device);
      mount_points_to_erase.push_back(mount_point);
    }
  }

  // Erase the |mount_info_map_| entries afterwards. Erasing in the loop above
  // using the iterator is slightly more efficient, but more tricky, since
  // calling std::map::erase() on an iterator invalidates it.
  for (std::list<base::FilePath>::const_iterator it =
           mount_points_to_erase.begin();
       it != mount_points_to_erase.end();
       ++it) {
    mount_info_map_.erase(*it);
  }

  // For any multiply mounted device where the mount that we had notified
  // got detached, send a notification of attachment for one of the other
  // mount points.
  for (std::list<base::FilePath>::const_iterator it =
           multiple_mounted_devices_needing_reattachment.begin();
       it != multiple_mounted_devices_needing_reattachment.end();
       ++it) {
    auto first_mount_point_info = mount_priority_map_.find(*it)->second.begin();
    const base::FilePath& mount_point = first_mount_point_info->first;
    first_mount_point_info->second = true;

    const StorageInfo& mount_info =
        mount_info_map_.find(mount_point)->second.storage_info;
    DCHECK(StorageInfo::IsRemovableDevice(mount_info.device_id()));
    receiver()->ProcessAttach(mount_info);
  }

  // Check new mtab entries against existing ones.
  scoped_refptr<base::SequencedTaskRunner> mounting_task_runner =
      base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
  for (auto new_iter = new_mtab.begin(); new_iter != new_mtab.end();
       ++new_iter) {
    const base::FilePath& mount_point = new_iter->first;
    const base::FilePath& mount_device = new_iter->second;
    auto old_iter = mount_info_map_.find(mount_point);
    if (old_iter == mount_info_map_.end() ||
        old_iter->second.mount_device != mount_device) {
      // New mount point found or an existing mount point found with a new
      // device.
      if (IsDeviceAlreadyMounted(mount_device)) {
        HandleDeviceMountedMultipleTimes(mount_device, mount_point);
      } else {
        base::PostTaskAndReplyWithResult(
            mounting_task_runner.get(), FROM_HERE,
            base::Bind(get_device_info_callback_, mount_device, mount_point),
            base::Bind(&StorageMonitorLinux::AddNewMount,
                       weak_ptr_factory_.GetWeakPtr(), mount_device));
      }
    }
  }

  // Note: Relies on scheduled tasks on the |mounting_task_runner| being
  // sequential. This block needs to follow the for loop, so that the DoNothing
  // call on the |mounting_task_runner| happens after the scheduled metadata
  // retrievals, meaning that the reply callback will then happen after all the
  // AddNewMount calls.
  if (!IsInitialized()) {
    mounting_task_runner->PostTaskAndReply(
        FROM_HERE, base::DoNothing(),
        base::Bind(&StorageMonitorLinux::MarkInitialized,
                   weak_ptr_factory_.GetWeakPtr()));
  }
}

bool StorageMonitorLinux::IsDeviceAlreadyMounted(
    const base::FilePath& mount_device) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return base::Contains(mount_priority_map_, mount_device);
}

void StorageMonitorLinux::HandleDeviceMountedMultipleTimes(
    const base::FilePath& mount_device,
    const base::FilePath& mount_point) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  auto priority = mount_priority_map_.find(mount_device);
  DCHECK(priority != mount_priority_map_.end());
  const base::FilePath& other_mount_point = priority->second.begin()->first;
  priority->second[mount_point] = false;
  mount_info_map_[mount_point] =
      mount_info_map_.find(other_mount_point)->second;
}

void StorageMonitorLinux::AddNewMount(
    const base::FilePath& mount_device,
    std::unique_ptr<StorageInfo> storage_info) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!storage_info)
    return;

  DCHECK(!storage_info->device_id().empty());

  bool removable = StorageInfo::IsRemovableDevice(storage_info->device_id());
  const base::FilePath mount_point(storage_info->location());

  MountPointInfo mount_point_info;
  mount_point_info.mount_device = mount_device;
  mount_point_info.storage_info = *storage_info;
  mount_info_map_[mount_point] = mount_point_info;
  mount_priority_map_[mount_device][mount_point] = removable;
  receiver()->ProcessAttach(*storage_info);
}

StorageMonitor* StorageMonitor::CreateInternal() {
  const base::FilePath kDefaultMtabPath("/etc/mtab");
  return new StorageMonitorLinux(kDefaultMtabPath);
}

}  // namespace storage_monitor
