| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/greasemonkey_master.h" | 5 #include "chrome/browser/greasemonkey_master.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 private: | 43 private: |
| 44 // Where functions are run: | 44 // Where functions are run: |
| 45 // master file | 45 // master file |
| 46 // StartScan -> RunScan | 46 // StartScan -> RunScan |
| 47 // GetNewScripts() | 47 // GetNewScripts() |
| 48 // NotifyMaster <- RunScan | 48 // NotifyMaster <- RunScan |
| 49 | 49 |
| 50 // Runs on the master thread. | 50 // Runs on the master thread. |
| 51 // Notify the master that new scripts are available. | 51 // Notify the master that new scripts are available. |
| 52 void NotifyMaster(SharedMemory* memory); | 52 void NotifyMaster(base::SharedMemory* memory); |
| 53 | 53 |
| 54 // Runs on the File thread. | 54 // Runs on the File thread. |
| 55 // Scan the script directory for scripts, calling NotifyMaster when done. | 55 // Scan the script directory for scripts, calling NotifyMaster when done. |
| 56 // The path is intentionally passed by value so its lifetime isn't tied | 56 // The path is intentionally passed by value so its lifetime isn't tied |
| 57 // to the caller. | 57 // to the caller. |
| 58 void RunScan(const FilePath script_dir); | 58 void RunScan(const FilePath script_dir); |
| 59 | 59 |
| 60 // Runs on the File thread. | 60 // Runs on the File thread. |
| 61 // Scan the script directory for scripts, returning either a new SharedMemory | 61 // Scan the script directory for scripts, returning either a new SharedMemory |
| 62 // or NULL on error. | 62 // or NULL on error. |
| 63 SharedMemory* GetNewScripts(const FilePath& script_dir); | 63 base::SharedMemory* GetNewScripts(const FilePath& script_dir); |
| 64 | 64 |
| 65 // A pointer back to our master. | 65 // A pointer back to our master. |
| 66 // May be NULL if DisownMaster() is called. | 66 // May be NULL if DisownMaster() is called. |
| 67 GreasemonkeyMaster* master_; | 67 GreasemonkeyMaster* master_; |
| 68 | 68 |
| 69 // The message loop to call our master back on. | 69 // The message loop to call our master back on. |
| 70 // Expected to always outlive us. | 70 // Expected to always outlive us. |
| 71 MessageLoop* master_message_loop_; | 71 MessageLoop* master_message_loop_; |
| 72 | 72 |
| 73 DISALLOW_COPY_AND_ASSIGN(ScriptReloader); | 73 DISALLOW_COPY_AND_ASSIGN(ScriptReloader); |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 void GreasemonkeyMaster::ScriptReloader::StartScan( | 76 void GreasemonkeyMaster::ScriptReloader::StartScan( |
| 77 MessageLoop* work_loop, | 77 MessageLoop* work_loop, |
| 78 const FilePath& script_dir) { | 78 const FilePath& script_dir) { |
| 79 // Add a reference to ourselves to keep ourselves alive while we're running. | 79 // Add a reference to ourselves to keep ourselves alive while we're running. |
| 80 // Balanced by NotifyMaster(). | 80 // Balanced by NotifyMaster(). |
| 81 AddRef(); | 81 AddRef(); |
| 82 work_loop->PostTask(FROM_HERE, | 82 work_loop->PostTask(FROM_HERE, |
| 83 NewRunnableMethod(this, | 83 NewRunnableMethod(this, |
| 84 &GreasemonkeyMaster::ScriptReloader::RunScan, | 84 &GreasemonkeyMaster::ScriptReloader::RunScan, |
| 85 script_dir)); | 85 script_dir)); |
| 86 } | 86 } |
| 87 | 87 |
| 88 void GreasemonkeyMaster::ScriptReloader::NotifyMaster(SharedMemory* memory) { | 88 void GreasemonkeyMaster::ScriptReloader::NotifyMaster( |
| 89 base::SharedMemory* memory) { |
| 89 if (!master_) { | 90 if (!master_) { |
| 90 // The master went away, so these new scripts aren't useful anymore. | 91 // The master went away, so these new scripts aren't useful anymore. |
| 91 delete memory; | 92 delete memory; |
| 92 } else { | 93 } else { |
| 93 master_->NewScriptsAvailable(memory); | 94 master_->NewScriptsAvailable(memory); |
| 94 } | 95 } |
| 95 | 96 |
| 96 // Drop our self-reference. | 97 // Drop our self-reference. |
| 97 // Balances StartScan(). | 98 // Balances StartScan(). |
| 98 Release(); | 99 Release(); |
| 99 } | 100 } |
| 100 | 101 |
| 101 void GreasemonkeyMaster::ScriptReloader::RunScan(const FilePath script_dir) { | 102 void GreasemonkeyMaster::ScriptReloader::RunScan(const FilePath script_dir) { |
| 102 SharedMemory* shared_memory = GetNewScripts(script_dir); | 103 base::SharedMemory* shared_memory = GetNewScripts(script_dir); |
| 103 | 104 |
| 104 // Post the new scripts back to the master's message loop. | 105 // Post the new scripts back to the master's message loop. |
| 105 master_message_loop_->PostTask(FROM_HERE, | 106 master_message_loop_->PostTask(FROM_HERE, |
| 106 NewRunnableMethod(this, | 107 NewRunnableMethod(this, |
| 107 &GreasemonkeyMaster::ScriptReloader::NotifyMaster, | 108 &GreasemonkeyMaster::ScriptReloader::NotifyMaster, |
| 108 shared_memory)); | 109 shared_memory)); |
| 109 } | 110 } |
| 110 | 111 |
| 111 SharedMemory* GreasemonkeyMaster::ScriptReloader::GetNewScripts( | 112 base::SharedMemory* GreasemonkeyMaster::ScriptReloader::GetNewScripts( |
| 112 const FilePath& script_dir) { | 113 const FilePath& script_dir) { |
| 113 std::vector<std::wstring> scripts; | 114 std::vector<std::wstring> scripts; |
| 114 | 115 |
| 115 file_util::FileEnumerator enumerator(script_dir.value(), false, | 116 file_util::FileEnumerator enumerator(script_dir.value(), false, |
| 116 file_util::FileEnumerator::FILES, | 117 file_util::FileEnumerator::FILES, |
| 117 L"*.user.js"); | 118 L"*.user.js"); |
| 118 for (std::wstring file = enumerator.Next(); !file.empty(); | 119 for (std::wstring file = enumerator.Next(); !file.empty(); |
| 119 file = enumerator.Next()) { | 120 file = enumerator.Next()) { |
| 120 scripts.push_back(file); | 121 scripts.push_back(file); |
| 121 } | 122 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 133 // TODO(aa): Support unicode script files. | 134 // TODO(aa): Support unicode script files. |
| 134 file_util::ReadFileToString(*path, &contents); | 135 file_util::ReadFileToString(*path, &contents); |
| 135 | 136 |
| 136 // Write scripts as 'data' so that we can read it out in the slave without | 137 // Write scripts as 'data' so that we can read it out in the slave without |
| 137 // allocating a new string. | 138 // allocating a new string. |
| 138 pickle.WriteData(file_url.c_str(), file_url.length()); | 139 pickle.WriteData(file_url.c_str(), file_url.length()); |
| 139 pickle.WriteData(contents.c_str(), contents.length()); | 140 pickle.WriteData(contents.c_str(), contents.length()); |
| 140 } | 141 } |
| 141 | 142 |
| 142 // Create the shared memory object. | 143 // Create the shared memory object. |
| 143 scoped_ptr<SharedMemory> shared_memory(new SharedMemory()); | 144 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); |
| 144 | 145 |
| 145 if (!shared_memory->Create(std::wstring(), // anonymous | 146 if (!shared_memory->Create(std::wstring(), // anonymous |
| 146 false, // read-only | 147 false, // read-only |
| 147 false, // open existing | 148 false, // open existing |
| 148 pickle.size())) { | 149 pickle.size())) { |
| 149 return NULL; | 150 return NULL; |
| 150 } | 151 } |
| 151 | 152 |
| 152 // Map into our process. | 153 // Map into our process. |
| 153 if (!shared_memory->Map(pickle.size())) | 154 if (!shared_memory->Map(pickle.size())) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 172 | 173 |
| 173 // (Asynchronously) scan for our initial set of scripts. | 174 // (Asynchronously) scan for our initial set of scripts. |
| 174 StartScan(); | 175 StartScan(); |
| 175 } | 176 } |
| 176 | 177 |
| 177 GreasemonkeyMaster::~GreasemonkeyMaster() { | 178 GreasemonkeyMaster::~GreasemonkeyMaster() { |
| 178 if (script_reloader_) | 179 if (script_reloader_) |
| 179 script_reloader_->DisownMaster(); | 180 script_reloader_->DisownMaster(); |
| 180 } | 181 } |
| 181 | 182 |
| 182 void GreasemonkeyMaster::NewScriptsAvailable(SharedMemory* handle) { | 183 void GreasemonkeyMaster::NewScriptsAvailable(base::SharedMemory* handle) { |
| 183 // Ensure handle is deleted or released. | 184 // Ensure handle is deleted or released. |
| 184 scoped_ptr<SharedMemory> handle_deleter(handle); | 185 scoped_ptr<base::SharedMemory> handle_deleter(handle); |
| 185 | 186 |
| 186 if (pending_scan_) { | 187 if (pending_scan_) { |
| 187 // While we were scanning, there were further changes. Don't bother | 188 // While we were scanning, there were further changes. Don't bother |
| 188 // notifying about these scripts and instead just immediately rescan. | 189 // notifying about these scripts and instead just immediately rescan. |
| 189 pending_scan_ = false; | 190 pending_scan_ = false; |
| 190 StartScan(); | 191 StartScan(); |
| 191 } else { | 192 } else { |
| 192 // We're no longer scanning. | 193 // We're no longer scanning. |
| 193 script_reloader_ = NULL; | 194 script_reloader_ = NULL; |
| 194 // We've got scripts ready to go. | 195 // We've got scripts ready to go. |
| 195 shared_memory_.swap(handle_deleter); | 196 shared_memory_.swap(handle_deleter); |
| 196 | 197 |
| 197 NotificationService::current()->Notify(NOTIFY_NEW_USER_SCRIPTS, | 198 NotificationService::current()->Notify(NOTIFY_NEW_USER_SCRIPTS, |
| 198 NotificationService::AllSources(), | 199 NotificationService::AllSources(), |
| 199 Details<SharedMemory>(handle)); | 200 Details<base::SharedMemory>(handle)); |
| 200 } | 201 } |
| 201 } | 202 } |
| 202 | 203 |
| 203 void GreasemonkeyMaster::OnDirectoryChanged(const FilePath& path) { | 204 void GreasemonkeyMaster::OnDirectoryChanged(const FilePath& path) { |
| 204 if (script_reloader_.get()) { | 205 if (script_reloader_.get()) { |
| 205 // We're already scanning for scripts. We note that we should rescan when | 206 // We're already scanning for scripts. We note that we should rescan when |
| 206 // we get the chance. | 207 // we get the chance. |
| 207 pending_scan_ = true; | 208 pending_scan_ = true; |
| 208 return; | 209 return; |
| 209 } | 210 } |
| 210 | 211 |
| 211 StartScan(); | 212 StartScan(); |
| 212 } | 213 } |
| 213 | 214 |
| 214 void GreasemonkeyMaster::StartScan() { | 215 void GreasemonkeyMaster::StartScan() { |
| 215 if (!script_reloader_) | 216 if (!script_reloader_) |
| 216 script_reloader_ = new ScriptReloader(this); | 217 script_reloader_ = new ScriptReloader(this); |
| 217 | 218 |
| 218 script_reloader_->StartScan(worker_loop_, *user_script_dir_); | 219 script_reloader_->StartScan(worker_loop_, *user_script_dir_); |
| 219 } | 220 } |
| OLD | NEW |