blob: 7baa8aa45787ec02328e01654b719a498a66bd94 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS 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 CROS_DISKS_ARCHIVE_MANAGER_H_
#define CROS_DISKS_ARCHIVE_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include <gtest/gtest_prod.h>
#include "cros-disks/mount_manager.h"
namespace cros_disks {
// A derived class of MountManager for mounting archive files as a virtual
// filesystem.
class ArchiveManager : public MountManager {
public:
ArchiveManager(const std::string& mount_root,
Platform* platform,
Metrics* metrics);
~ArchiveManager() override;
// Initializes the manager and registers default file extensions.
// Returns true on success.
bool Initialize() override;
// Stops a session. Returns true on success.
bool StopSession() override;
// Returns true if mounting |source_path| is supported.
bool CanMount(const std::string& source_path) const override;
// Returns the type of mount sources supported by the manager.
MountSourceType GetMountSourceType() const override {
return MOUNT_SOURCE_ARCHIVE;
}
// Registers a set of default archive file extensions to the manager.
void RegisterDefaultFileExtensions();
// Registers an archive file extension and the corresponding AVFS handler to
// to the manager. Subsequent registrations of the same file extension
// overwrite an existing handler. |extension| should not include the leading
// dot. |avfs_handler| should be in the form like '#uzip', '#ugz#utar', etc.
void RegisterFileExtension(const std::string& extension,
const std::string& avfs_handler);
protected:
// Mounts |source_path| to |mount_path| as |source_format| with |options|.
// |source_format| can be used to specify the archive file format of
// |source_path|, so that |source_path| can have any file extension.
// If |source_format| is an empty string, the archive file format is
// determined based on the file extension of |source_path|. The underlying
// mounter may decide to apply mount options different than |options|.
// |applied_options| is used to return the mount options applied by the
// mounter.
MountErrorType DoMount(const std::string& source_path,
const std::string& source_format,
const std::vector<std::string>& options,
const std::string& mount_path,
MountOptions* applied_options) override;
// Unmounts |path| with |options|. Returns true if |path| is unmounted
// successfully.
MountErrorType DoUnmount(const std::string& path,
const std::vector<std::string>& options) override;
// Returns a suggested mount path for a source path.
std::string SuggestMountPath(const std::string& source_path) const override;
private:
// Type definition of a cache mapping a mount path to its source virtual path
// in the AVFS mount.
using VirtualPathMap = std::map<std::string, std::string>;
// Returns the extension of a file, in lower case, at the specified |path|.
std::string GetFileExtension(const std::string& path) const;
// Returns the corresponding path inside the AVFS mount of a given |path|
// with the archive file |extension|, or an empty string if |extension| is
// not supported or |path| does not have a corresponding path inside the AVFS
// mount.
std::string GetAVFSPath(const std::string& path,
const std::string& extension) const;
// Starts AVFS daemons to initialize AVFS mounts. Returns true on success or
// if the AVFS daemons have started.
bool StartAVFS();
// Stops AVFS daemons and unmounts AVFS mounts. Returns true on success or if
// the AVFS daemons have not yet started.
bool StopAVFS();
// Mounts |base_path| to |avfs_path| via AVFS. Return true on success.
bool MountAVFSPath(const std::string& base_path,
const std::string& avfs_path) const;
// Adds a mapping of |mount_path| to |virtual_path| to |virtual_paths_|.
// An existing mapping of |mount_path| is overwritten.
void AddMountVirtualPath(const std::string& mount_path,
const std::string& virtual_path);
// Removes a mapping of |mount_path| to its virtual path from
// |virtual_paths_|. It is a no-op if no such mapping exists.
void RemoveMountVirtualPath(const std::string& mount_path);
// A mapping of supported archive file extensions to corresponding AVFS
// handlers.
std::map<std::string, std::string> extension_handlers_;
// A cache mapping a mount path to its source virtual path in the AVFS mount.
VirtualPathMap virtual_paths_;
// This variable is set to true if the AVFS daemons have started.
bool avfs_started_;
FRIEND_TEST(ArchiveManagerTest, GetAVFSPath);
FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithInvalidPaths);
FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithUnsupportedExtensions);
FRIEND_TEST(ArchiveManagerTest, GetAVFSPathWithNestedArchives);
FRIEND_TEST(ArchiveManagerTest, GetFileExtension);
FRIEND_TEST(ArchiveManagerTest, SuggestMountPath);
FRIEND_TEST(ArchiveManagerTest, DoMountFailedWithUnsupportedExtension);
};
} // namespace cros_disks
#endif // CROS_DISKS_ARCHIVE_MANAGER_H_