Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1525)

Unified Diff: chrome/browser/media_gallery/media_storage_util.cc

Issue 10829384: SystemMonitor: Pull device type into the device id (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media_gallery/media_storage_util.cc
diff --git a/chrome/browser/media_gallery/media_storage_util.cc b/chrome/browser/media_gallery/media_storage_util.cc
new file mode 100644
index 0000000000000000000000000000000000000000..73ede71174fc93389e921053e3457666a4652f28
--- /dev/null
+++ b/chrome/browser/media_gallery/media_storage_util.cc
@@ -0,0 +1,235 @@
+// Copyright (c) 2012 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.
+
+// chrome::MediaStorageUtil implementation.
kmadhusu 2012/08/17 18:53:35 nit: Comment is not required.
vandebo (ex-Chrome) 2012/08/17 22:55:51 In Lei's readability review the reviewer suggested
+
+#include "chrome/browser/media_gallery/media_storage_util.h"
+
+#include <vector>
+
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/lazy_instance.h"
kmadhusu 2012/08/17 18:53:35 lazy_instance is included both in .h and .cc file.
vandebo (ex-Chrome) 2012/08/17 22:55:51 And used in neither. Fixed.
+#include "base/logging.h"
+#include "base/system_monitor/system_monitor.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace chrome {
+
+namespace {
+
+typedef std::vector<base::SystemMonitor::MediaDeviceInfo> MediaDevicesInfo;
+
+const char kUsbMassStorageWithDCIMPrefix[] = "dcim:";
kmadhusu 2012/08/17 18:53:35 nit: // Media device unique id prefix constants.
vandebo (ex-Chrome) 2012/08/17 22:55:51 Done. (Added a more "why" comment than you sugges
+const char kUsbMassStorageNoDCIMPrefix[] = "usb:";
+const char kOtherMassStoragePrefix[] = "path:";
+const char kUsbMtpPrefix[] = "mtp:";
+
+void EmptyPathIsFalseCallback(const base::Callback<void(bool)>& callback,
kmadhusu 2012/08/17 18:53:35 Document this helper function.
vandebo (ex-Chrome) 2012/08/17 22:55:51 I think the name and body are pretty self descript
+ FilePath path) {
kmadhusu 2012/08/17 18:53:35 nit: "const FilePath&"
vandebo (ex-Chrome) 2012/08/17 22:55:51 This can't be const because it has to match the Fi
+ callback.Run(!path.empty());
+}
+
+void ValidatePathOnFileThread(const FilePath& path,
+ const base::Callback<void(FilePath)>& callback) {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
kmadhusu 2012/08/17 18:53:35 nit: Add using content::BrowserThread;
vandebo (ex-Chrome) 2012/08/20 18:35:14 Done.
+ FilePath result;
+ if (file_util::PathExists(path))
+ result = path;
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, path));
+}
+
+FilePath MakePathRelative(FilePath path) {
kmadhusu 2012/08/17 18:53:35 nit: GetRelativePath nit: const FilePath& nit: Doc
vandebo (ex-Chrome) 2012/08/17 22:55:51 Done.
+ if (!path.IsAbsolute())
+ return path;
+
+ FilePath relative;
+ std::vector<FilePath::StringType> components;
+ path.GetComponents(&components);
+
+ // On Windows, the first component may be the drive letter with the second
+ // being \\.
+ int start = 1;
+ if (components[1].size() == 1 && FilePath::IsSeparator(components[1][0]))
+ start = 2;
+
+ for (size_t i = start; i < components.size(); i++)
+ relative = relative.Append(components[i]);
+ return relative;
+}
+
+} // namespace
+
+// static
+std::string MediaStorageUtil::MakeDeviceId(Type type,
kmadhusu 2012/08/17 18:53:35 nit: const Type& nit: DCHECK(!unique_id.empty());
vandebo (ex-Chrome) 2012/08/17 22:55:51 I don't think we usually use const ref's for enums
+ const std::string& unique_id) {
+ switch (type) {
+ case USB_MASS_STORAGE_WITH_DCIM:
+ return std::string(kUsbMassStorageWithDCIMPrefix) + unique_id;
+ case USB_MASS_STORAGE_NO_DCIM:
+ return std::string(kUsbMassStorageNoDCIMPrefix) + unique_id;
+ case OTHER_MASS_STORAGE:
+ return std::string(kOtherMassStoragePrefix) + unique_id;
+ case USB_MTP:
+ return std::string(kUsbMtpPrefix) + unique_id;
+ default:
+ NOTREACHED();
+ return std::string();
kmadhusu 2012/08/17 18:53:35 Can we return a bool to notify failure?
vandebo (ex-Chrome) 2012/08/17 22:55:51 Failure shouldn't happen, hence the NOTREACHED.
kmadhusu 2012/08/20 17:13:49 (repeating our offline discussion): There is a cha
vandebo (ex-Chrome) 2012/08/20 18:35:14 Our in person conversation was about corrupt prefe
+ }
+}
+
+// static
+void MediaStorageUtil::CrackDeviceId(const std::string& device_id,
+ Type* type, std::string* unique_id) {
+ size_t prefix_length = device_id.find_first_of(':');
+ std::string prefix = device_id.substr(0, prefix_length);
+
+ if (type) {
+ if (prefix == kUsbMassStorageWithDCIMPrefix) {
+ *type = USB_MASS_STORAGE_WITH_DCIM;
+ } else if (prefix == kUsbMassStorageNoDCIMPrefix) {
+ *type = USB_MASS_STORAGE_NO_DCIM;
+ } else if (prefix == kOtherMassStoragePrefix) {
+ *type = OTHER_MASS_STORAGE;
+ } else if (prefix == kUsbMtpPrefix) {
+ *type = USB_MTP;
+ } else {
+ NOTREACHED();
kmadhusu 2012/08/17 18:53:35 Can we return a bool to notify failure?
vandebo (ex-Chrome) 2012/08/17 22:55:51 Failure shouldn't happen, hence the NOTREACHED.
kmadhusu 2012/08/20 17:13:49 same here.
vandebo (ex-Chrome) 2012/08/20 18:35:14 Done.
+ }
+ }
+
+ if (unique_id)
+ *unique_id = device_id.substr(prefix_length + 1);
+}
+
+// static
+bool MediaStorageUtil::IsMediaDevice(const std::string& device_id) {
+ Type type;
+ CrackDeviceId(device_id, &type, NULL);
+ return type == USB_MASS_STORAGE_WITH_DCIM || type == USB_MTP;
+}
+
+// static
+bool MediaStorageUtil::IsRemovableDevice(const std::string& device_id) {
+ Type type;
+ CrackDeviceId(device_id, &type, NULL);
+ return type != OTHER_MASS_STORAGE;
+}
+
+// static
+void MediaStorageUtil::IsDeviceAttached(
+ const std::string& device_id, const base::Callback<void(bool)>& callback) {
+ Type type;
+ std::string unique_id;
+ CrackDeviceId(device_id, &type, &unique_id);
+
+ switch (type) {
+ case USB_MTP: // Fall through
+ case USB_MASS_STORAGE_WITH_DCIM: {
+ // We should be able to find media devices in SystemMonitor.
+ MediaDevicesInfo media_devices =
+ base::SystemMonitor::Get()->GetAttachedMediaDevices();
kmadhusu 2012/08/17 18:53:35 Add a helper function in SystemMonitor to check wh
vandebo (ex-Chrome) 2012/08/17 22:55:51 What advantage would that have?
kmadhusu 2012/08/20 17:13:49 As we discussed, you can leave this as it is.
vandebo (ex-Chrome) 2012/08/20 18:35:14 As you suggested, I pulled the duplicated code int
+ for (MediaDevicesInfo::const_iterator it = media_devices.begin();
+ it != media_devices.end();
+ ++it) {
+ if (it->unique_id == device_id) {
+ callback.Run(true);
+ return;
+ }
+ }
+ callback.Run(false);
+ break;
+ }
+ case USB_MASS_STORAGE_NO_DCIM:
+ FindUSBDeviceById(unique_id,
+ base::Bind(&EmptyPathIsFalseCallback, callback));
kmadhusu 2012/08/17 18:53:35 nit: Can we rename "EmptyPathIsFalseCallback" ?
vandebo (ex-Chrome) 2012/08/17 22:55:51 Do you have a suggestion? I think it's a descript
+ break;
+ case OTHER_MASS_STORAGE:
+ // For this type, the unique_id is the path.
+ content::BrowserThread::PostTask(
+ content::BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ValidatePathOnFileThread,
+ FilePath::FromUTF8Unsafe(unique_id),
+ base::Bind(&EmptyPathIsFalseCallback, callback)));
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+// static
+void MediaStorageUtil::GetDeviceInfoFromPath(
+ const FilePath& input,
+ const base::Callback<void(std::string, FilePath, string16)>& callback) {
+ // TODO(vandebo) This needs to be implemented per platform. Below is no
+ // worse than what the code already does.
+ // * Find mount point parent (determines relative file path)
+ // * Search System monitor, just in case.
+ // * If it's a USB device, generate device id, else use device root path as id
+ std::string device_id =
+ MakeDeviceId(OTHER_MASS_STORAGE, input.AsUTF8Unsafe());
+ FilePath relative_path = MakePathRelative(input);
+ string16 display_name = input.BaseName().LossyDisplayName();
+
+ callback.Run(device_id, relative_path, display_name);
+ return;
+}
+
+// static
+void MediaStorageUtil::FindDevicePathById(
+ const std::string& device_id,
+ const base::Callback<void(FilePath)>& callback) {
+ Type type;
+ std::string unique_id;
+ CrackDeviceId(device_id, &type, &unique_id);
+
+ switch (type) {
+ case USB_MTP:
+ callback.Run(FilePath());
+ break;
+ case USB_MASS_STORAGE_NO_DCIM:
+ FindUSBDeviceById(unique_id, callback);
+ break;
+ case OTHER_MASS_STORAGE:
+ // For this type, the unique_id is the path.
+ content::BrowserThread::PostTask(
+ content::BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ValidatePathOnFileThread,
+ FilePath::FromUTF8Unsafe(unique_id), callback));
+ break;
+ case USB_MASS_STORAGE_WITH_DCIM: {
+ FilePath result;
+ MediaDevicesInfo media_devices =
+ base::SystemMonitor::Get()->GetAttachedMediaDevices();
kmadhusu 2012/08/17 18:53:35 nit: using base::SystemMonitor;
vandebo (ex-Chrome) 2012/08/20 18:35:14 Done.
+ for (MediaDevicesInfo::const_iterator it = media_devices.begin();
+ it != media_devices.end();
+ ++it) {
+ if (it->unique_id == device_id) {
+ result = FilePath(it->location);
+ break;
+ }
+ }
+ callback.Run(result);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+MediaStorageUtil::MediaStorageUtil() {}
+
+// static
+void MediaStorageUtil::FindUSBDeviceById(
+ const std::string unique_id,
+ const base::Callback<void(FilePath)>& callback) {
+ // TODO(vandebo) This needs to be implemented per platform.
+ // Type is USB_MASS_STORAGE_NO_DCIM, so it's a device possibly mounted
+ // somewhere...
+ NOTREACHED();
+ callback.Run(FilePath());
+}
+
+} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698