blob: 5e0ae0fd98e579c1cd6b895a4458b94ab5e1afee [file] [log] [blame]
// Copyright 2018 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 CHROME_CHROME_CLEANER_OS_FILE_REMOVAL_STATUS_UPDATER_H_
#define CHROME_CHROME_CLEANER_OS_FILE_REMOVAL_STATUS_UPDATER_H_
#include <map>
#include <unordered_map>
#include "base/files/file_path.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "chrome/chrome_cleaner/logging/proto/removal_status.pb.h"
namespace chrome_cleaner {
namespace internal {
// RemovalStatus update control utilities, exposed in the internal namespace so
// they can be accessed by tests.
// Indicates the action to be taken on RemovalStatus updates for files and
// folders.
enum RemovalStatusOverridePermission {
// Ignore, this is expected and we shouldn't change the current value.
// Example: updating removal status to NOT_FOUND after deleting the file.
kSkip,
// Override, this is an actual update and we should keep the most recent
// value. Example: updating removal status to FAILED_TO_SCHEDULE_REMOVAL
// when previous knowledge was FAILED_TO_REMOVE.
kOkToOverride,
// This should never happen in the code, and we should raise an error.
// TODO(joenotcharles): Currently there is no error, and kNotAllowed is
// implemented as kSkip. This is because DCHECK writes an error message to
// the log, and until recently this took the logging lock which might already
// be held while checking this permission. Now that it's safe to DCHECK while
// the logging lock is held we should add a DCHECK.
kNotAllowed,
};
// Maps pairs of RemovalStatus to the expected permission.
typedef std::map<RemovalStatus,
std::map<RemovalStatus, RemovalStatusOverridePermission>>
RemovalStatusOverridePermissionMap;
// Returns the overriding map.
const RemovalStatusOverridePermissionMap&
GetRemovalStatusOverridePermissionMap();
} // namespace internal
// This class manages a map of remove statuses for all files and folders
// encountered during cleaning, keyed by path. It does not distinguish whether
// the path refers to a file or a folder.
class FileRemovalStatusUpdater {
public:
struct FileRemovalStatus {
// The full path that was passed to UpdateRemovalStatus or
// UpdateQuarantineStatus. This is needed because when a file removal status
// is logged, GetFileInformationProtoObject can be called, which needs a
// full path that can be resolved.
base::FilePath path;
// The removal status of the last attempted update at the above path.
RemovalStatus removal_status = REMOVAL_STATUS_UNSPECIFIED;
// The quarantine status of the last attempted update at the above path.
QuarantineStatus quarantine_status = QUARANTINE_STATUS_UNSPECIFIED;
};
typedef std::unordered_map<base::string16, FileRemovalStatus>
SanitizedPathToRemovalStatusMap;
static FileRemovalStatusUpdater* GetInstance();
virtual ~FileRemovalStatusUpdater();
// Clears all saved removal statuses.
void Clear();
// Updates removal status for a file or folder given by |path|. Checks the
// RemovalStatusOverridePermissionMap to see if the update is allowed, and
// silently does nothing if the permission is kSkip.
void UpdateRemovalStatus(const base::FilePath& path, RemovalStatus status);
// Returns the removal status of |path|, or REMOVAL_STATUS_UNSPECIFIED if
// the removal status have never been updated for that path.
RemovalStatus GetRemovalStatus(const base::FilePath& path) const;
// Returns the removal status of |sanitized_path|, or
// REMOVAL_STATUS_UNSPECIFIED if the removal status have never
// been updated for an unsanitized form of that path.
RemovalStatus GetRemovalStatusOfSanitizedPath(
const base::string16& sanitized_path) const;
// Updates quarantine status for a file given by |path|.
// Note: UpdateRemovalStatus should be called for |path| at some point as
// well, because it is invalid to quarantine a file that doesn't have some
// removal status.
void UpdateQuarantineStatus(const base::FilePath& path,
QuarantineStatus status);
// Returns the quarantine status of |path|, or QUARANTINE_STATUS_UNSPECIFIED
// if the quarantine status have never been updated for that path.
QuarantineStatus GetQuarantineStatus(const base::FilePath& path) const;
// Returns all saved removal statuses, keyed by sanitized path. Each
// sanitized path is mapped to a single FileRemovalStatus which holds the
// path and status values from the most recent call to UpdateRemovalStatus or
// UpdateQuarantineStatus that had an effect.
SanitizedPathToRemovalStatusMap GetAllRemovalStatuses() const;
private:
friend struct base::DefaultSingletonTraits<FileRemovalStatusUpdater>;
FileRemovalStatusUpdater();
// Locks access to |removal_statuses_|.
mutable base::Lock removal_status_lock_;
SanitizedPathToRemovalStatusMap removal_statuses_;
};
} // namespace chrome_cleaner
#endif // CHROME_CHROME_CLEANER_OS_FILE_REMOVAL_STATUS_UPDATER_H_