| Index: chromeos/memory/low_memory_listener.cc
|
| diff --git a/chrome/browser/chromeos/memory/low_memory_observer.cc b/chromeos/memory/low_memory_listener.cc
|
| similarity index 61%
|
| rename from chrome/browser/chromeos/memory/low_memory_observer.cc
|
| rename to chromeos/memory/low_memory_listener.cc
|
| index 90fd869d0985db3554608be00b4d6b7eb30e905c..a53e7b7bae8c8469a0e735568536c789e3415454 100644
|
| --- a/chrome/browser/chromeos/memory/low_memory_observer.cc
|
| +++ b/chromeos/memory/low_memory_listener.cc
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "chrome/browser/chromeos/memory/low_memory_observer.h"
|
| +#include "chromeos/memory/low_memory_listener.h"
|
|
|
| #include <fcntl.h>
|
|
|
| @@ -12,9 +12,7 @@
|
| #include "base/message_loop.h"
|
| #include "base/time.h"
|
| #include "base/timer.h"
|
| -#include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/browser_process_platform_part_chromeos.h"
|
| -#include "chrome/browser/chromeos/memory/oom_priority_manager.h"
|
| +#include "chromeos/memory/low_memory_listener_delegate.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/zygote_host_linux.h"
|
|
|
| @@ -34,26 +32,26 @@ const int kLowMemoryCheckTimeoutMs = 750;
|
| } // namespace
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// LowMemoryObserverImpl
|
| +// LowMemoryListenerImpl
|
| //
|
| // Does the actual work of observing. The observation work happens on the FILE
|
| -// thread, and the discarding of tabs happens on the UI thread.
|
| -// If low memory is detected, then we discard a tab, wait
|
| -// kLowMemoryCheckTimeoutMs milliseconds and then start watching again to see
|
| -// if we're still in a low memory state. This is to keep from discarding all
|
| -// tabs the first time we enter the state, because it takes time for the
|
| -// tabs to deallocate their memory. A timer isn't the perfect solution, but
|
| -// without any reliable indicator that a tab has had all its parts deallocated,
|
| -// it's the next best thing.
|
| -class LowMemoryObserverImpl
|
| - : public base::RefCountedThreadSafe<LowMemoryObserverImpl> {
|
| +// thread, and notification happens on the UI thread. If low memory is
|
| +// detected, then we notify, wait kLowMemoryCheckTimeoutMs milliseconds and then
|
| +// start watching again to see if we're still in a low memory state. This is to
|
| +// keep from sending out multiple notifications before the UI has a chance to
|
| +// respond (it may take the UI a while to actually deallocate memory). A timer
|
| +// isn't the perfect solution, but without any reliable indicator that a tab has
|
| +// had all its parts deallocated, it's the next best thing.
|
| +class LowMemoryListenerImpl
|
| + : public base::RefCountedThreadSafe<LowMemoryListenerImpl> {
|
| public:
|
| - LowMemoryObserverImpl() : watcher_delegate_(this), file_descriptor_(-1) {}
|
| + LowMemoryListenerImpl() : watcher_delegate_(this), file_descriptor_(-1) {}
|
|
|
| // Start watching the low memory file for readability.
|
| // Calls to StartObserving should always be matched with calls to
|
| // StopObserving. This method should only be called from the FILE thread.
|
| - void StartObservingOnFileThread();
|
| + // |low_memory_callback| is run when memory is low.
|
| + void StartObservingOnFileThread(const base::Closure& low_memory_callback);
|
|
|
| // Stop watching the low memory file for readability.
|
| // May be safely called if StartObserving has not been called.
|
| @@ -61,9 +59,9 @@ class LowMemoryObserverImpl
|
| void StopObservingOnFileThread();
|
|
|
| private:
|
| - friend class base::RefCountedThreadSafe<LowMemoryObserverImpl>;
|
| + friend class base::RefCountedThreadSafe<LowMemoryListenerImpl>;
|
|
|
| - ~LowMemoryObserverImpl() {
|
| + ~LowMemoryListenerImpl() {
|
| StopObservingOnFileThread();
|
| }
|
|
|
| @@ -76,7 +74,7 @@ class LowMemoryObserverImpl
|
| // Delegate to receive events from WatchFileDescriptor.
|
| class FileWatcherDelegate : public MessageLoopForIO::Watcher {
|
| public:
|
| - explicit FileWatcherDelegate(LowMemoryObserverImpl* owner)
|
| + explicit FileWatcherDelegate(LowMemoryListenerImpl* owner)
|
| : owner_(owner) {}
|
| virtual ~FileWatcherDelegate() {}
|
|
|
| @@ -85,36 +83,29 @@ class LowMemoryObserverImpl
|
| virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
|
| LOG(WARNING) << "Low memory condition detected. Discarding a tab.";
|
| // We can only discard tabs on the UI thread.
|
| - base::Callback<void(void)> callback = base::Bind(&DiscardTab);
|
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
| + BrowserThread::PostTask(BrowserThread::UI,
|
| + FROM_HERE,
|
| + owner_->low_memory_callback_);
|
| owner_->ScheduleNextObservation();
|
| }
|
|
|
| - // Sends off a discard request to the OomPriorityManager. Must be run on
|
| - // the UI thread.
|
| - static void DiscardTab() {
|
| - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - if (g_browser_process &&
|
| - g_browser_process->platform_part()->oom_priority_manager()) {
|
| - g_browser_process->platform_part()->
|
| - oom_priority_manager()->LogMemoryAndDiscardTab();
|
| - }
|
| - }
|
| -
|
| private:
|
| - LowMemoryObserverImpl* owner_;
|
| + LowMemoryListenerImpl* owner_;
|
| DISALLOW_COPY_AND_ASSIGN(FileWatcherDelegate);
|
| };
|
|
|
| scoped_ptr<MessageLoopForIO::FileDescriptorWatcher> watcher_;
|
| FileWatcherDelegate watcher_delegate_;
|
| int file_descriptor_;
|
| - base::OneShotTimer<LowMemoryObserverImpl> timer_;
|
| + base::OneShotTimer<LowMemoryListenerImpl> timer_;
|
| + base::Closure low_memory_callback_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(LowMemoryObserverImpl);
|
| + DISALLOW_COPY_AND_ASSIGN(LowMemoryListenerImpl);
|
| };
|
|
|
| -void LowMemoryObserverImpl::StartObservingOnFileThread() {
|
| +void LowMemoryListenerImpl::StartObservingOnFileThread(
|
| + const base::Closure& low_memory_callback) {
|
| + low_memory_callback_ = low_memory_callback;
|
| DCHECK_LE(file_descriptor_, 0)
|
| << "Attempted to start observation when it was already started.";
|
| DCHECK(watcher_.get() == NULL);
|
| @@ -132,7 +123,7 @@ void LowMemoryObserverImpl::StartObservingOnFileThread() {
|
| StartWatchingDescriptor();
|
| }
|
|
|
| -void LowMemoryObserverImpl::StopObservingOnFileThread() {
|
| +void LowMemoryListenerImpl::StopObservingOnFileThread() {
|
| // If StartObserving failed, StopObserving will still get called.
|
| timer_.Stop();
|
| if (file_descriptor_ >= 0) {
|
| @@ -143,14 +134,14 @@ void LowMemoryObserverImpl::StopObservingOnFileThread() {
|
| }
|
| }
|
|
|
| -void LowMemoryObserverImpl::ScheduleNextObservation() {
|
| +void LowMemoryListenerImpl::ScheduleNextObservation() {
|
| timer_.Start(FROM_HERE,
|
| base::TimeDelta::FromMilliseconds(kLowMemoryCheckTimeoutMs),
|
| this,
|
| - &LowMemoryObserverImpl::StartWatchingDescriptor);
|
| + &LowMemoryListenerImpl::StartWatchingDescriptor);
|
| }
|
|
|
| -void LowMemoryObserverImpl::StartWatchingDescriptor() {
|
| +void LowMemoryListenerImpl::StartWatchingDescriptor() {
|
| DCHECK(watcher_.get());
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| DCHECK(MessageLoopForIO::current());
|
| @@ -167,31 +158,41 @@ void LowMemoryObserverImpl::StartWatchingDescriptor() {
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// LowMemoryObserver
|
| +// LowMemoryListener
|
|
|
| -LowMemoryObserver::LowMemoryObserver() : observer_(new LowMemoryObserverImpl) {}
|
| +LowMemoryListener::LowMemoryListener(LowMemoryListenerDelegate* delegate)
|
| + : observer_(new LowMemoryListenerImpl),
|
| + delegate_(delegate),
|
| + weak_factory_(this) {
|
| +}
|
|
|
| -LowMemoryObserver::~LowMemoryObserver() { Stop(); }
|
| +LowMemoryListener::~LowMemoryListener() {
|
| + Stop();
|
| +}
|
|
|
| -void LowMemoryObserver::Start() {
|
| +void LowMemoryListener::Start() {
|
| + base::Closure memory_low_callback =
|
| + base::Bind(&LowMemoryListener::OnMemoryLow, weak_factory_.GetWeakPtr());
|
| BrowserThread::PostTask(
|
| BrowserThread::FILE,
|
| FROM_HERE,
|
| - base::Bind(&LowMemoryObserverImpl::StartObservingOnFileThread,
|
| - observer_.get()));
|
| + base::Bind(&LowMemoryListenerImpl::StartObservingOnFileThread,
|
| + observer_.get(),
|
| + memory_low_callback));
|
| }
|
|
|
| -void LowMemoryObserver::Stop() {
|
| +void LowMemoryListener::Stop() {
|
| + weak_factory_.InvalidateWeakPtrs();
|
| BrowserThread::PostTask(
|
| BrowserThread::FILE,
|
| FROM_HERE,
|
| - base::Bind(&LowMemoryObserverImpl::StopObservingOnFileThread,
|
| + base::Bind(&LowMemoryListenerImpl::StopObservingOnFileThread,
|
| observer_.get()));
|
| }
|
|
|
| -// static
|
| -void LowMemoryObserver::SetLowMemoryMargin(int64 margin_mb) {
|
| - content::ZygoteHost::GetInstance()->AdjustLowMemoryMargin(margin_mb);
|
| +void LowMemoryListener::OnMemoryLow() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + delegate_->OnMemoryLow();
|
| }
|
|
|
| } // namespace chromeos
|
|
|