Commit 4b8fa62a authored by nya's avatar nya Committed by Commit bot

mediaview: Mount ARC documents provider file system volumes.

New media view volumes are added to chromeos::VolumeManager so that they are
available to Files.app. UI patches are coming later, so at this point it looks like
unusable unknown volumes appear in Files.app. To hide them from users for now,
the feature is guarded with base::FeatureList. Once UI is ready I will make them
enabled by default.

BUG=chromium:671511
TEST=New (unusable) volumes are shown with --enable-features=ArcMediaView
TEST=Media views work with local pending UI patches

Review-Url: https://codereview.chromium.org/2580303002
Cr-Commit-Position: refs/heads/master@{#443205}
parent 9b7705c2
......@@ -263,6 +263,8 @@ source_set("chromeos") {
"arc/fileapi/arc_file_system_instance_util.h",
"arc/fileapi/arc_file_system_service.cc",
"arc/fileapi/arc_file_system_service.h",
"arc/fileapi/arc_media_view_util.cc",
"arc/fileapi/arc_media_view_util.h",
"arc/intent_helper/arc_external_protocol_dialog.cc",
"arc/intent_helper/arc_external_protocol_dialog.h",
"arc/intent_helper/arc_navigation_throttle.cc",
......
......@@ -14,11 +14,48 @@
namespace arc {
// This is based on net/base/escape.cc: net::(anonymous namespace)::Escape.
// TODO(nya): Consider consolidating this function with EscapeFileSystemId() in
// chrome/browser/chromeos/file_system_provider/mount_path_util.cc.
// This version differs from the other one in the point that dots are not always
// escaped because authorities often contain harmless dots.
std::string EscapePathComponent(const std::string& name) {
std::string escaped;
// Escape dots only when they forms a special file name.
if (name == "." || name == "..") {
base::ReplaceChars(name, ".", "%2E", &escaped);
return escaped;
}
// Escape % and / only.
for (size_t i = 0; i < name.size(); ++i) {
const char c = name[i];
if (c == '%' || c == '/')
base::StringAppendF(&escaped, "%%%02X", c);
else
escaped.push_back(c);
}
return escaped;
}
std::string UnescapePathComponent(const std::string& escaped) {
return net::UnescapeURLComponent(
escaped, net::UnescapeRule::PATH_SEPARATORS |
net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
}
const char kDocumentsProviderMountPointName[] = "arc-documents-provider";
const base::FilePath::CharType kDocumentsProviderMountPointPath[] =
"/special/arc-documents-provider";
const char kAndroidDirectoryMimeType[] = "vnd.android.document/directory";
base::FilePath GetDocumentsProviderMountPath(
const std::string& authority,
const std::string& root_document_id) {
return base::FilePath(kDocumentsProviderMountPointPath)
.Append(EscapePathComponent(authority))
.Append(EscapePathComponent(root_document_id));
}
bool ParseDocumentsProviderUrl(const storage::FileSystemURL& url,
std::string* authority,
std::string* root_document_id,
......@@ -39,12 +76,11 @@ bool ParseDocumentsProviderUrl(const storage::FileSystemURL& url,
if (components.size() < 5)
return false;
*authority = components[3];
*root_document_id = components[4];
*authority = UnescapePathComponent(components[3]);
*root_document_id = UnescapePathComponent(components[4]);
base::FilePath root_path = base::FilePath(kDocumentsProviderMountPointPath)
.Append(*authority)
.Append(*root_document_id);
base::FilePath root_path =
GetDocumentsProviderMountPath(*authority, *root_document_id);
// Special case: AppendRelativePath() fails for identical paths.
if (url_path_stripped == root_path) {
path->clear();
......
......@@ -29,7 +29,28 @@ extern const base::FilePath::CharType kDocumentsProviderMountPointPath[];
// Defined as DocumentsContract.Document.MIME_TYPE_DIR in Android.
extern const char kAndroidDirectoryMimeType[];
// Escapes a string so it can be used as a file/directory name.
// [%/.] are escaped with percent-encoding.
// NOTE: This function is visible only for unit testing. Usually you should not
// call this function directly.
std::string EscapePathComponent(const std::string& name);
// Unescapes a string escaped by EscapePathComponent().
// NOTE: This function is visible only for unit testing. Usually you should not
// call this function directly.
std::string UnescapePathComponent(const std::string& escaped);
// Returns the path of a directory where the specified DocumentsProvider is
// mounted.
// Appropriate escaping is done to embed |authority| and |root_document_id| in
// a file path.
base::FilePath GetDocumentsProviderMountPath(
const std::string& authority,
const std::string& root_document_id);
// Parses a FileSystemURL pointing to ARC documents provider file system.
// Appropriate unescaping is done to extract |authority| and |root_document_id|
// from |url|.
// On success, true is returned. All arguments must not be nullptr.
bool ParseDocumentsProviderUrl(const storage::FileSystemURL& url,
std::string* authority,
......
......@@ -12,6 +12,45 @@ namespace arc {
namespace {
TEST(ArcDocumentsProviderUtilTest, EscapePathComponent) {
EXPECT_EQ("", EscapePathComponent(""));
EXPECT_EQ("%2E", EscapePathComponent("."));
EXPECT_EQ("%2E%2E", EscapePathComponent(".."));
EXPECT_EQ("...", EscapePathComponent("..."));
EXPECT_EQ("example.com", EscapePathComponent("example.com"));
EXPECT_EQ("%2F%2F%2F", EscapePathComponent("///"));
EXPECT_EQ("100%25", EscapePathComponent("100%"));
EXPECT_EQ("a b", EscapePathComponent("a b"));
EXPECT_EQ("ねこ", EscapePathComponent("ねこ"));
}
TEST(ArcDocumentsProviderUtilTest, UnescapePathComponent) {
EXPECT_EQ("", UnescapePathComponent(""));
EXPECT_EQ(".", UnescapePathComponent("%2E"));
EXPECT_EQ("..", UnescapePathComponent("%2E%2E"));
EXPECT_EQ("...", UnescapePathComponent("..."));
EXPECT_EQ("example.com", UnescapePathComponent("example.com"));
EXPECT_EQ("///", UnescapePathComponent("%2F%2F%2F"));
EXPECT_EQ("100%", UnescapePathComponent("100%25"));
EXPECT_EQ("a b", UnescapePathComponent("a b"));
EXPECT_EQ("ねこ", UnescapePathComponent("ねこ"));
}
TEST(ArcDocumentsProviderUtilTest, GetDocumentsProviderMountPath) {
EXPECT_EQ("/special/arc-documents-provider/authority/document_id",
GetDocumentsProviderMountPath("authority", "document_id").value());
EXPECT_EQ("/special/arc-documents-provider/a b/a b",
GetDocumentsProviderMountPath("a b", "a b").value());
EXPECT_EQ("/special/arc-documents-provider/a%2Fb/a%2Fb",
GetDocumentsProviderMountPath("a/b", "a/b").value());
EXPECT_EQ("/special/arc-documents-provider/%2E/%2E",
GetDocumentsProviderMountPath(".", ".").value());
EXPECT_EQ("/special/arc-documents-provider/%2E%2E/%2E%2E",
GetDocumentsProviderMountPath("..", "..").value());
EXPECT_EQ("/special/arc-documents-provider/.../...",
GetDocumentsProviderMountPath("...", "...").value());
}
TEST(ArcDocumentsProviderUtilTest, ParseDocumentsProviderUrl) {
std::string authority;
std::string root_document_id;
......@@ -118,6 +157,22 @@ TEST(ArcDocumentsProviderUtilTest, ParseDocumentsProviderUrlInvalidPath) {
&authority, &root_document_id, &path));
}
TEST(ArcDocumentsProviderUtilTest, ParseDocumentsProviderUrlUnescape) {
std::string authority;
std::string root_document_id;
base::FilePath path;
EXPECT_TRUE(ParseDocumentsProviderUrl(
storage::FileSystemURL::CreateForTest(
GURL(), storage::kFileSystemTypeArcDocumentsProvider,
base::FilePath(
"/special/arc-documents-provider/cats/ro%2Fot/home/calico.jpg")),
&authority, &root_document_id, &path));
EXPECT_EQ("cats", authority);
EXPECT_EQ("ro/ot", root_document_id);
EXPECT_EQ(FILE_PATH_LITERAL("home/calico.jpg"), path.value());
}
TEST(ArcDocumentsProviderUtilTest, ParseDocumentsProviderUrlUtf8) {
std::string authority;
std::string root_document_id;
......@@ -135,8 +190,13 @@ TEST(ArcDocumentsProviderUtilTest, ParseDocumentsProviderUrlUtf8) {
}
TEST(ArcDocumentsProviderUtilTest, BuildDocumentUrl) {
EXPECT_EQ("content://Cat%20Provider/document/C%2B%2B",
BuildDocumentUrl("Cat Provider", "C++").spec());
EXPECT_EQ("content://authority/document/document_id",
BuildDocumentUrl("authority", "document_id").spec());
EXPECT_EQ("content://a%20b/document/a%20b",
BuildDocumentUrl("a b", "a b").spec());
EXPECT_EQ("content://a%2Fb/document/a%2Fb",
BuildDocumentUrl("a/b", "a/b").spec());
EXPECT_EQ("content://../document/..", BuildDocumentUrl("..", "..").spec());
}
} // namespace
......
......@@ -8,6 +8,7 @@
#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_url_util.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/file_system/arc_file_system_observer.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/fileapi/external_mount_points.h"
......@@ -15,6 +16,10 @@ using content::BrowserThread;
namespace arc {
// static
const char ArcFileSystemService::kArcServiceName[] =
"arc::ArcFileSystemService";
ArcFileSystemService::ArcFileSystemService(ArcBridgeService* bridge_service)
: ArcService(bridge_service) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
......@@ -31,11 +36,15 @@ ArcFileSystemService::ArcFileSystemService(ArcBridgeService* bridge_service)
storage::kFileSystemTypeArcDocumentsProvider,
storage::FileSystemMountOption(),
base::FilePath(kDocumentsProviderMountPointPath));
arc_bridge_service()->file_system()->AddObserver(this);
}
ArcFileSystemService::~ArcFileSystemService() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
arc_bridge_service()->file_system()->RemoveObserver(this);
storage::ExternalMountPoints* mount_points =
storage::ExternalMountPoints::GetSystemInstance();
......@@ -43,4 +52,22 @@ ArcFileSystemService::~ArcFileSystemService() {
mount_points->RevokeFileSystem(kDocumentsProviderMountPointPath);
}
void ArcFileSystemService::AddObserver(ArcFileSystemObserver* observer) {
observer_list_.AddObserver(observer);
}
void ArcFileSystemService::RemoveObserver(ArcFileSystemObserver* observer) {
observer_list_.RemoveObserver(observer);
}
void ArcFileSystemService::OnInstanceReady() {
for (auto& observer : observer_list_)
observer.OnFileSystemsReady();
}
void ArcFileSystemService::OnInstanceClosed() {
for (auto& observer : observer_list_)
observer.OnFileSystemsClosed();
}
} // namespace arc
......@@ -6,19 +6,37 @@
#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_FILE_SYSTEM_SERVICE_H_
#include "base/macros.h"
#include "base/observer_list.h"
#include "components/arc/arc_service.h"
#include "components/arc/common/file_system.mojom.h"
#include "components/arc/instance_holder.h"
namespace arc {
class ArcBridgeService;
class ArcFileSystemObserver;
// ArcFileSystemService registers ARC file systems to the system.
class ArcFileSystemService : public ArcService {
class ArcFileSystemService
: public ArcService,
public InstanceHolder<mojom::FileSystemInstance>::Observer {
public:
explicit ArcFileSystemService(ArcBridgeService* bridge_service);
~ArcFileSystemService() override;
void AddObserver(ArcFileSystemObserver* observer);
void RemoveObserver(ArcFileSystemObserver* observer);
// InstanceHolder<mojom::FileSystemInstance>::Observer overrides:
void OnInstanceReady() override;
void OnInstanceClosed() override;
// For supporting ArcServiceManager::GetService<T>().
static const char kArcServiceName[];
private:
base::ObserverList<ArcFileSystemObserver> observer_list_;
DISALLOW_COPY_AND_ASSIGN(ArcFileSystemService);
};
......
// Copyright 2017 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.
#include "chrome/browser/chromeos/arc/fileapi/arc_media_view_util.h"
namespace arc {
namespace {
constexpr char kMediaViewVolumeIdPrefix[] = "media_view:";
} // namespace
const base::Feature kMediaViewFeature{"ArcMediaView",
base::FEATURE_DISABLED_BY_DEFAULT};
const char kMediaDocumentsProviderAuthority[] =
"com.android.providers.media.documents";
const char kImagesRootDocumentId[] = "images_root";
const char kVideosRootDocumentId[] = "videos_root";
const char kAudioRootDocumentId[] = "audio_root";
std::string GetMediaViewVolumeId(const std::string& root_document_id) {
return std::string(kMediaViewVolumeIdPrefix) + root_document_id;
}
} // namespace arc
// Copyright 2017 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.
//
// Utilities for ARC Media View.
#ifndef CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_MEDIA_VIEW_UTIL_H_
#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_MEDIA_VIEW_UTIL_H_
#include <string>
#include "base/feature_list.h"
namespace arc {
// base::FeatureList feature for ARC media view.
extern const base::Feature kMediaViewFeature;
// Authority of MediaDocumentsProvider in Android.
extern const char kMediaDocumentsProviderAuthority[];
// Document IDs of file system roots in MediaDocumentsProvider.
extern const char kImagesRootDocumentId[];
extern const char kVideosRootDocumentId[];
extern const char kAudioRootDocumentId[];
// Returns an ID of a Media View volume.
std::string GetMediaViewVolumeId(const std::string& root_document_id);
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_MEDIA_VIEW_UTIL_H_
......@@ -242,6 +242,10 @@ void VolumeToVolumeMetadata(
case VOLUME_TYPE_MTP:
volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_MTP;
break;
case VOLUME_TYPE_MEDIA_VIEW:
volume_metadata->volume_type =
file_manager_private::VOLUME_TYPE_MEDIA_VIEW;
break;
case VOLUME_TYPE_TESTING:
volume_metadata->volume_type =
file_manager_private::VOLUME_TYPE_TESTING;
......
......@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
......@@ -16,6 +17,10 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/arc/arc_session_manager.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_file_system_service.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_media_view_util.h"
#include "chrome/browser/chromeos/drive/drive_integration_service.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
......@@ -29,6 +34,7 @@
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "components/arc/arc_service_manager.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/file_system_core_util.h"
#include "components/prefs/pref_service.h"
......@@ -111,6 +117,8 @@ std::string VolumeTypeToString(VolumeType type) {
return "provided";
case VOLUME_TYPE_MTP:
return "mtp";
case VOLUME_TYPE_MEDIA_VIEW:
return "media_view";
case VOLUME_TYPE_TESTING:
return "testing";
case NUM_VOLUME_TYPE:
......@@ -270,6 +278,22 @@ Volume* Volume::CreateForMTP(const base::FilePath& mount_path,
return volume;
}
// static
Volume* Volume::CreateForMediaView(const std::string& root_document_id) {
Volume* const volume = new Volume;
volume->type_ = VOLUME_TYPE_MEDIA_VIEW;
volume->device_type_ = chromeos::DEVICE_TYPE_UNKNOWN;
volume->source_ = SOURCE_SYSTEM;
volume->mount_path_ = arc::GetDocumentsProviderMountPath(
arc::kMediaDocumentsProviderAuthority, root_document_id);
volume->mount_condition_ = chromeos::disks::MOUNT_CONDITION_NONE;
volume->volume_label_ = root_document_id;
volume->is_read_only_ = true;
volume->watchable_ = false;
volume->volume_id_ = arc::GetMediaViewVolumeId(root_document_id);
return volume;
}
// static
Volume* Volume::CreateForTesting(const base::FilePath& path,
VolumeType volume_type,
......@@ -382,6 +406,13 @@ void VolumeManager::Initialize() {
base::Bind(&VolumeManager::OnStorageMonitorInitialized,
weak_ptr_factory_.GetWeakPtr()));
}
// Subscribe to ARC file system events.
if (base::FeatureList::IsEnabled(arc::kMediaViewFeature) &&
arc::ArcSessionManager::IsAllowedForProfile(profile_)) {
arc::ArcServiceManager::GetGlobalService<arc::ArcFileSystemService>()
->AddObserver(this);
}
}
void VolumeManager::Shutdown() {
......@@ -398,6 +429,17 @@ void VolumeManager::Shutdown() {
if (file_system_provider_service_)
file_system_provider_service_->RemoveObserver(this);
// Unsubscribe from ARC file system events.
if (base::FeatureList::IsEnabled(arc::kMediaViewFeature) &&
arc::ArcSessionManager::IsAllowedForProfile(profile_)) {
arc::ArcFileSystemService* file_system_service =
arc::ArcServiceManager::GetGlobalService<arc::ArcFileSystemService>();
// TODO(crbug.com/672829): We need nullptr check here because
// ArcServiceManager may or may not be alive at this point.
if (file_system_service)
file_system_service->RemoveObserver(this);
}
}
void VolumeManager::AddObserver(VolumeManagerObserver* observer) {
......@@ -702,6 +744,38 @@ void VolumeManager::OnExternalStorageDisabledChangedUnmountCallback(
weak_ptr_factory_.GetWeakPtr()));
}
void VolumeManager::OnFileSystemsReady() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(base::FeatureList::IsEnabled(arc::kMediaViewFeature));
DCHECK(arc::ArcSessionManager::IsAllowedForProfile(profile_));
DoMountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kImagesRootDocumentId)));
DoMountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kVideosRootDocumentId)));
DoMountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kAudioRootDocumentId)));
}
void VolumeManager::OnFileSystemsClosed() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(base::FeatureList::IsEnabled(arc::kMediaViewFeature));
DCHECK(arc::ArcSessionManager::IsAllowedForProfile(profile_));
DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kImagesRootDocumentId)));
DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kVideosRootDocumentId)));
DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
linked_ptr<Volume>(
Volume::CreateForMediaView(arc::kAudioRootDocumentId)));
}
void VolumeManager::OnExternalStorageDisabledChanged() {
// If the policy just got disabled we have to unmount every device currently
// mounted. The opposite is fine - we can let the user re-plug their device to
......
......@@ -22,6 +22,7 @@
#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "chromeos/disks/disk_mount_manager.h"
#include "components/arc/file_system/arc_file_system_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/storage_monitor/removable_storage_observer.h"
......@@ -51,6 +52,7 @@ enum VolumeType {
VOLUME_TYPE_MOUNTED_ARCHIVE_FILE,
VOLUME_TYPE_PROVIDED, // File system provided by the FileSystemProvider API.
VOLUME_TYPE_MTP,
VOLUME_TYPE_MEDIA_VIEW,
// The enum values must be kept in sync with FileManagerVolumeType in
// tools/metrics/histograms/histograms.xml. Since enums for histograms are
// append-only (for keeping the number consistent across versions), new values
......@@ -90,6 +92,7 @@ class Volume : public base::SupportsWeakPtr<Volume> {
static Volume* CreateForMTP(const base::FilePath& mount_path,
const std::string& label,
bool read_only);
static Volume* CreateForMediaView(const std::string& root_document_id);
static Volume* CreateForTesting(const base::FilePath& path,
VolumeType volume_type,
chromeos::DeviceType device_type,
......@@ -211,6 +214,7 @@ class Volume : public base::SupportsWeakPtr<Volume> {
// for a device).
// - Mounted zip archives.
class VolumeManager : public KeyedService,
public arc::ArcFileSystemObserver,
public drive::DriveIntegrationServiceObserver,
public chromeos::disks::DiskMountManager::Observer,
public chromeos::file_system_provider::Observer,
......@@ -297,6 +301,10 @@ class VolumeManager : public KeyedService,
file_system_info,
base::File::Error error) override;
// arc::ArcFileSystemObserver overrides.
void OnFileSystemsReady() override;
void OnFileSystemsClosed() override;
// Called on change to kExternalStorageDisabled pref.
void OnExternalStorageDisabledChanged();
......
......@@ -11,12 +11,14 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h"
#include "chrome/browser/chromeos/fileapi/file_access_permissions.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
#include "chrome/common/url_constants.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "net/base/escape.h"
#include "storage/browser/fileapi/async_file_util.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_stream_reader.h"
......@@ -26,6 +28,7 @@
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/common/fileapi/file_system_mount_option.h"
#include "storage/common/fileapi/file_system_util.h"
namespace chromeos {
namespace {
......@@ -156,6 +159,27 @@ void FileSystemBackend::ResolveURL(const storage::FileSystemURL& url,
std::string inner_mount_name = components[1];
root_url += inner_mount_name + "/";
name = inner_mount_name;
} else if (id == arc::kDocumentsProviderMountPointName) {
// For ARC documents provider file system, volumes are mounted per document
// provider root, so we need to fix up |root_url| to point to an individual
// root.
std::string authority;
std::string root_document_id;
base::FilePath unused_path;
if (!arc::ParseDocumentsProviderUrl(url, &authority, &root_document_id,
&unused_path)) {
callback.Run(GURL(root_url), std::string(),
base::File::FILE_ERROR_SECURITY);
return;
}
base::FilePath mount_path =
arc::GetDocumentsProviderMountPath(authority, root_document_id);
base::FilePath relative_mount_path;
base::FilePath(arc::kDocumentsProviderMountPointPath)
.AppendRelativePath(mount_path, &relative_mount_path);
root_url +=
net::EscapePath(storage::FilePathToString(relative_mount_path)) + "/";
name = authority + ":" + root_document_id;
} else {
name = id;
}
......
......@@ -9,7 +9,7 @@
namespace fileManagerPrivate {
// Type of the mounted volume.
enum VolumeType { drive, downloads, removable, archive, provided, mtp,
testing };
media_view, testing };
// Device type. Available if this is removable volume.
enum DeviceType { usb, sd, optical, mobile, unknown };
......
......@@ -21,6 +21,7 @@ static_library("arc") {
"clipboard/arc_clipboard_bridge.h",
"crash_collector/arc_crash_collector_bridge.cc",
"crash_collector/arc_crash_collector_bridge.h",
"file_system/arc_file_system_observer.h",
"ime/arc_ime_bridge.h",
"ime/arc_ime_bridge_impl.cc",
"ime/arc_ime_bridge_impl.h",
......
// Copyright 2017 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.
#ifndef COMPONENTS_ARC_FILE_SYSTEM_ARC_FILE_SYSTEM_OBSERVER_H_
#define COMPONENTS_ARC_FILE_SYSTEM_ARC_FILE_SYSTEM_OBSERVER_H_
namespace arc {
class ArcFileSystemObserver {
public:
virtual ~ArcFileSystemObserver() = default;
// Called when ARC file systems are ready.
virtual void OnFileSystemsReady() = 0;
// Called when ARC file systems are closed.
virtual void OnFileSystemsClosed() = 0;
};
} // namespace arc
#endif // COMPONENTS_ARC_FILE_SYSTEM_ARC_FILE_SYSTEM_OBSERVER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment