summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync_file_system/local/root_delete_helper.cc
blob: 63a90008b862a5e082a7edde3cea69a640842afc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2013 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/sync_file_system/local/root_delete_helper.h"

#include "base/sequenced_task_runner.h"
#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
#include "chrome/browser/sync_file_system/local/local_file_sync_status.h"
#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
#include "chrome/browser/sync_file_system/logger.h"
#include "chrome/browser/sync_file_system/sync_callbacks.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
#include "storage/common/fileapi/file_system_util.h"

namespace sync_file_system {

namespace {

// This runs on FileSystemContext's default_file_task_runner.
void ResetFileChangeTracker(storage::FileSystemContext* file_system_context,
                            const storage::FileSystemURL& url) {
  DCHECK(file_system_context->default_file_task_runner()->
             RunsTasksOnCurrentThread());
  SyncFileSystemBackend* backend =
      SyncFileSystemBackend::GetBackend(file_system_context);
  DCHECK(backend);
  DCHECK(backend->change_tracker());
  backend->change_tracker()->ResetForFileSystem(url.origin(), url.type());
}

}  // namespace

RootDeleteHelper::RootDeleteHelper(
    storage::FileSystemContext* file_system_context,
    LocalFileSyncStatus* sync_status,
    const storage::FileSystemURL& url,
    const FileStatusCallback& callback)
    : file_system_context_(file_system_context),
      url_(url),
      callback_(callback),
      sync_status_(sync_status),
      weak_factory_(this) {
  DCHECK(file_system_context_.get());
  DCHECK(url_.is_valid());
  DCHECK(!callback_.is_null());
  DCHECK(sync_status_);
  // This is expected to run on the filesystem root.
  DCHECK(storage::VirtualPath::IsRootPath(url.path()));
}

RootDeleteHelper::~RootDeleteHelper() {
}

void RootDeleteHelper::Run() {
  util::Log(logging::LOG_VERBOSE, FROM_HERE,
            "Deleting the entire local filesystem for remote root deletion: "
            "%s", url_.DebugString().c_str());

  file_system_context_->DeleteFileSystem(
      url_.origin(), url_.type(),
      base::Bind(&RootDeleteHelper::DidDeleteFileSystem,
                 weak_factory_.GetWeakPtr()));
}

void RootDeleteHelper::DidDeleteFileSystem(base::File::Error error) {
  // Ignore errors, no idea how to deal with it.

  DCHECK(!sync_status_->IsWritable(url_));
  DCHECK(!sync_status_->IsWriting(url_));

  // All writes to the entire file system must be now blocked, so we have
  // to be able to safely reset the local changes and sync statuses for it.
  // TODO(kinuko): This should be probably automatically handled in
  // DeleteFileSystem via QuotaUtil::DeleteOriginDataOnFileThread.
  file_system_context_->default_file_task_runner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&ResetFileChangeTracker, file_system_context_, url_),
      base::Bind(&RootDeleteHelper::DidResetFileChangeTracker,
                 weak_factory_.GetWeakPtr()));
}

void RootDeleteHelper::DidResetFileChangeTracker() {
  DCHECK(!sync_status_->IsWritable(url_));
  DCHECK(!sync_status_->IsWriting(url_));

  // Reopening the filesystem.
  file_system_context_->sandbox_delegate()->OpenFileSystem(
      url_.origin(),
      url_.type(),
      storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
      base::Bind(&RootDeleteHelper::DidOpenFileSystem,
                 weak_factory_.GetWeakPtr()),
      GURL());
}

void RootDeleteHelper::DidOpenFileSystem(const GURL& /* root */,
                                         const std::string& /* name */,
                                         base::File::Error error) {
  FileStatusCallback callback = callback_;
  callback.Run(error);
}

}  // namespace sync_file_system