1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/metrics/thread_watcher_android.h" 6 7#include "base/android/application_status_listener.h" 8#include "base/command_line.h" 9#include "base/lazy_instance.h" 10#include "chrome/browser/metrics/thread_watcher.h" 11 12namespace { 13 14// For most of the activities, the C++ side is initialized asynchronously 15// and the very first APPLICATION_STATE_HAS_RUNNING_ACTIVITIES is never received 16// whilst the ThreadWatcherList is initiated higher up in the stack. 17// However, some activities are initialized synchronously, and it'll receive 18// an APPLICATION_STATE_HAS_RUNNING_ACTIVITIES here as well. 19// Protect against this case, and only let 20// APPLICATION_STATE_HAS_RUNNING_ACTIVITIES turn on the 21// watchdog if it was previously handled by an 22// APPLICATION_STATE_HAS_STOPPED_ACTIVITIES (which is always handled here). 23bool g_application_has_stopped = false; 24 25void OnApplicationStateChange( 26 base::android::ApplicationState application_state) { 27 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 28 if (application_state == 29 base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES) { 30 g_application_has_stopped = true; 31 ThreadWatcherList::StopWatchingAll(); 32 } else if (application_state == 33 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES && 34 g_application_has_stopped) { 35 g_application_has_stopped = false; 36 ThreadWatcherList::StartWatchingAll(*CommandLine::ForCurrentProcess()); 37 } 38} 39 40struct LeakyApplicationStatusListenerTraits { 41 static const bool kRegisterOnExit = false; 42#ifndef NDEBUG 43 static const bool kAllowedToAccessOnNonjoinableThread = true; 44#endif 45 46 static base::android::ApplicationStatusListener* New(void* instance) { 47 ANNOTATE_SCOPED_MEMORY_LEAK; 48 return new (instance) base::android::ApplicationStatusListener( 49 base::Bind(&OnApplicationStateChange)); 50 } 51 52 static void Delete(base::android::ApplicationStatusListener* instance) { 53 } 54}; 55 56base::LazyInstance<base::android::ApplicationStatusListener, 57 LeakyApplicationStatusListenerTraits> 58 g_application_status_listener = LAZY_INSTANCE_INITIALIZER; 59 60} // namespace 61 62void ThreadWatcherAndroid::RegisterApplicationStatusListener() { 63 // Leaky. 64 g_application_status_listener.Get(); 65} 66