Home | History | Annotate | Download | only in metrics
      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 
     12 namespace {
     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).
     23 bool g_application_has_stopped = false;
     24 
     25 void 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 
     40 struct 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 
     56 base::LazyInstance<base::android::ApplicationStatusListener,
     57                    LeakyApplicationStatusListenerTraits>
     58     g_application_status_listener = LAZY_INSTANCE_INITIALIZER;
     59 
     60 }  // namespace
     61 
     62 void ThreadWatcherAndroid::RegisterApplicationStatusListener() {
     63   // Leaky.
     64   g_application_status_listener.Get();
     65 }
     66