• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OnApplicationStateChange(base::android::ApplicationState application_state)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 
New__anon01cee14e0111::LeakyApplicationStatusListenerTraits46   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 
Delete__anon01cee14e0111::LeakyApplicationStatusListenerTraits52   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 
RegisterApplicationStatusListener()62 void ThreadWatcherAndroid::RegisterApplicationStatusListener() {
63   // Leaky.
64   g_application_status_listener.Get();
65 }
66