Commit 2eaab0b3 authored by lushnikov's avatar lushnikov Committed by Commit bot

DevTools: improve DevTools file watcher to send added and removed paths

Currently, DevTools file watcher reports both added and changed paths
as "changed" and doesn't report removed paths.

This patch improves DevTools file watcher so that it starts reporting
changed, added and removed paths.

BUG=none
R=dgozman, pfeldman

Review-Url: https://codereview.chromium.org/2384343002
Cr-Commit-Position: refs/heads/master@{#422838}
parent 2ae51c4e
...@@ -456,6 +456,8 @@ void DevToolsFileHelper::FileSystemPathsSettingChanged() { ...@@ -456,6 +456,8 @@ void DevToolsFileHelper::FileSystemPathsSettingChanged() {
} }
void DevToolsFileHelper::FilePathsChanged( void DevToolsFileHelper::FilePathsChanged(
const std::vector<std::string>& paths) { const std::vector<std::string>& changed_paths,
delegate_->FilePathsChanged(paths); const std::vector<std::string>& added_paths,
const std::vector<std::string>& removed_paths) {
delegate_->FilePathsChanged(changed_paths, added_paths, removed_paths);
} }
...@@ -47,7 +47,10 @@ class DevToolsFileHelper { ...@@ -47,7 +47,10 @@ class DevToolsFileHelper {
virtual ~Delegate() {} virtual ~Delegate() {}
virtual void FileSystemAdded(const FileSystem& file_system) = 0; virtual void FileSystemAdded(const FileSystem& file_system) = 0;
virtual void FileSystemRemoved(const std::string& file_system_path) = 0; virtual void FileSystemRemoved(const std::string& file_system_path) = 0;
virtual void FilePathsChanged(const std::vector<std::string>& paths) = 0; virtual void FilePathsChanged(
const std::vector<std::string>& changed_paths,
const std::vector<std::string>& added_paths,
const std::vector<std::string>& removed_paths) = 0;
}; };
DevToolsFileHelper(content::WebContents* web_contents, Profile* profile, DevToolsFileHelper(content::WebContents* web_contents, Profile* profile,
...@@ -132,7 +135,9 @@ class DevToolsFileHelper { ...@@ -132,7 +135,9 @@ class DevToolsFileHelper {
const base::FilePath& path, const base::FilePath& path,
bool allowed); bool allowed);
void FileSystemPathsSettingChanged(); void FileSystemPathsSettingChanged();
void FilePathsChanged(const std::vector<std::string>& paths); void FilePathsChanged(const std::vector<std::string>& changed_paths,
const std::vector<std::string>& added_paths,
const std::vector<std::string>& removed_paths);
content::WebContents* web_contents_; content::WebContents* web_contents_;
Profile* profile_; Profile* profile_;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/files/file_enumerator.h" #include "base/files/file_enumerator.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/files/file_path_watcher.h" #include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -38,13 +39,15 @@ class DevToolsFileWatcher::SharedFileWatcher : ...@@ -38,13 +39,15 @@ class DevToolsFileWatcher::SharedFileWatcher :
DevToolsFileWatcher::SharedFileWatcher>; DevToolsFileWatcher::SharedFileWatcher>;
~SharedFileWatcher(); ~SharedFileWatcher();
using FilePathTimesMap = std::map<base::FilePath, base::Time>;
void GetModificationTimes(const base::FilePath& path,
FilePathTimesMap* file_path_times);
void DirectoryChanged(const base::FilePath& path, bool error); void DirectoryChanged(const base::FilePath& path, bool error);
void DispatchNotifications(); void DispatchNotifications();
std::vector<DevToolsFileWatcher*> listeners_; std::vector<DevToolsFileWatcher*> listeners_;
std::map<base::FilePath, std::unique_ptr<base::FilePathWatcher>> watchers_; std::map<base::FilePath, std::unique_ptr<base::FilePathWatcher>> watchers_;
using FilePathTimesMap = std::map<base::FilePath, base::Time>; std::map<base::FilePath, FilePathTimesMap> file_path_times_;
FilePathTimesMap file_path_times_;
std::set<base::FilePath> pending_paths_; std::set<base::FilePath> pending_paths_;
base::Time last_event_time_; base::Time last_event_time_;
base::TimeDelta last_dispatch_cost_; base::TimeDelta last_dispatch_cost_;
...@@ -84,11 +87,17 @@ void DevToolsFileWatcher::SharedFileWatcher::AddWatch( ...@@ -84,11 +87,17 @@ void DevToolsFileWatcher::SharedFileWatcher::AddWatch(
if (!success) if (!success)
return; return;
GetModificationTimes(path, &file_path_times_[path]);
}
void DevToolsFileWatcher::SharedFileWatcher::GetModificationTimes(
const base::FilePath& path,
FilePathTimesMap* times_map) {
base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES); base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES);
base::FilePath file_path = enumerator.Next(); base::FilePath file_path = enumerator.Next();
while (!file_path.empty()) { while (!file_path.empty()) {
base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); base::FileEnumerator::FileInfo file_info = enumerator.GetInfo();
file_path_times_[file_path] = file_info.GetLastModifiedTime(); (*times_map)[file_path] = file_info.GetLastModifiedTime();
file_path = enumerator.Next(); file_path = enumerator.Next();
} }
} }
...@@ -121,26 +130,38 @@ void DevToolsFileWatcher::SharedFileWatcher::DirectoryChanged( ...@@ -121,26 +130,38 @@ void DevToolsFileWatcher::SharedFileWatcher::DirectoryChanged(
} }
void DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications() { void DevToolsFileWatcher::SharedFileWatcher::DispatchNotifications() {
if (!pending_paths_.size())
return;
base::Time start = base::Time::Now(); base::Time start = base::Time::Now();
std::vector<std::string> added_paths;
std::vector<std::string> removed_paths;
std::vector<std::string> changed_paths; std::vector<std::string> changed_paths;
for (auto path : pending_paths_) {
base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES); for (const auto& path : pending_paths_) {
base::FilePath file_path = enumerator.Next(); FilePathTimesMap& old_times = file_path_times_[path];
while (!file_path.empty()) { FilePathTimesMap current_times;
base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); GetModificationTimes(path, &current_times);
base::Time new_time = file_info.GetLastModifiedTime(); for (const auto& path_time : current_times) {
if (file_path_times_[file_path] != new_time) { const base::FilePath& path = path_time.first;
file_path_times_[file_path] = new_time; auto old_timestamp = old_times.find(path);
changed_paths.push_back(file_path.AsUTF8Unsafe()); if (old_timestamp == old_times.end())
} added_paths.push_back(path.AsUTF8Unsafe());
file_path = enumerator.Next(); else if (old_timestamp->second != path_time.second)
changed_paths.push_back(path.AsUTF8Unsafe());
}
for (const auto& path_time : old_times) {
const base::FilePath& path = path_time.first;
if (current_times.find(path) == current_times.end())
removed_paths.push_back(path.AsUTF8Unsafe());
} }
old_times.swap(current_times);
} }
pending_paths_.clear(); pending_paths_.clear();
for (auto* watcher : listeners_) { for (auto* watcher : listeners_) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(watcher->callback_, changed_paths)); base::Bind(watcher->callback_, changed_paths,
added_paths, removed_paths));
} }
last_dispatch_cost_ = base::Time::Now() - start; last_dispatch_cost_ = base::Time::Now() - start;
} }
......
...@@ -17,7 +17,9 @@ class FilePathWatcher; ...@@ -17,7 +17,9 @@ class FilePathWatcher;
class DevToolsFileWatcher { class DevToolsFileWatcher {
public: public:
using WatchCallback = base::Callback<void(const std::vector<std::string>&)>; using WatchCallback = base::Callback<void(const std::vector<std::string>&,
const std::vector<std::string>&,
const std::vector<std::string>&)>;
explicit DevToolsFileWatcher(const WatchCallback& callback); explicit DevToolsFileWatcher(const WatchCallback& callback);
~DevToolsFileWatcher(); ~DevToolsFileWatcher();
......
...@@ -977,10 +977,17 @@ void DevToolsUIBindings::FileSystemRemoved( ...@@ -977,10 +977,17 @@ void DevToolsUIBindings::FileSystemRemoved(
} }
void DevToolsUIBindings::FilePathsChanged( void DevToolsUIBindings::FilePathsChanged(
const std::vector<std::string>& file_paths) { const std::vector<std::string>& changed_paths,
const std::vector<std::string>& added_paths,
const std::vector<std::string>& removed_paths) {
base::ListValue list; base::ListValue list;
for (auto path : file_paths) for (auto path : changed_paths)
list.AppendString(path);
for (auto path : added_paths)
list.AppendString(path); list.AppendString(path);
for (auto path : removed_paths)
list.AppendString(path);
CallClientFunction("DevToolsAPI.fileSystemFilesChanged", CallClientFunction("DevToolsAPI.fileSystemFilesChanged",
&list, NULL, NULL); &list, NULL, NULL);
} }
......
...@@ -177,7 +177,9 @@ class DevToolsUIBindings : public DevToolsEmbedderMessageDispatcher::Delegate, ...@@ -177,7 +177,9 @@ class DevToolsUIBindings : public DevToolsEmbedderMessageDispatcher::Delegate,
void FileSystemAdded( void FileSystemAdded(
const DevToolsFileHelper::FileSystem& file_system) override; const DevToolsFileHelper::FileSystem& file_system) override;
void FileSystemRemoved(const std::string& file_system_path) override; void FileSystemRemoved(const std::string& file_system_path) override;
void FilePathsChanged(const std::vector<std::string>& file_paths) override; void FilePathsChanged(const std::vector<std::string>& changed_paths,
const std::vector<std::string>& added_paths,
const std::vector<std::string>& removed_paths) override;
// DevToolsFileHelper callbacks. // DevToolsFileHelper callbacks.
void FileSavedAs(const std::string& url); void FileSavedAs(const std::string& url);
......
...@@ -194,9 +194,12 @@ DevToolsAPIImpl.prototype = { ...@@ -194,9 +194,12 @@ DevToolsAPIImpl.prototype = {
this._dispatchOnInspectorFrontendAPI("fileSystemAdded", ["", fileSystem]); this._dispatchOnInspectorFrontendAPI("fileSystemAdded", ["", fileSystem]);
}, },
fileSystemFilesChanged: function(path) /**
* @param {!Array<string>} changedPaths
*/
fileSystemFilesChanged: function(changedPaths)
{ {
this._dispatchOnInspectorFrontendAPI("fileSystemFilesChanged", [path]); this._dispatchOnInspectorFrontendAPI("fileSystemFilesChanged", [changedPaths]);
}, },
/** /**
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
*/ */
WebInspector.IsolatedFileSystemManager = function() WebInspector.IsolatedFileSystemManager = function()
{ {
WebInspector.Object.call(this);
/** @type {!Map<string, !WebInspector.IsolatedFileSystem>} */ /** @type {!Map<string, !WebInspector.IsolatedFileSystem>} */
this._fileSystems = new Map(); this._fileSystems = new Map();
/** @type {!Map<number, function(!Array.<string>)>} */ /** @type {!Map<number, function(!Array.<string>)>} */
......
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