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
6#include "base/android/application_status_listener.h"
7#include "base/run_loop.h"
8#include "base/synchronization/waitable_event.h"
9#include "chrome/browser/metrics/thread_watcher.h"
10#include "chrome/browser/metrics/thread_watcher_android.h"
11#include "content/public/test/test_browser_thread.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14using content::BrowserThread;
15
16namespace {
17void OnThreadWatcherTask(base::WaitableEvent* event) {
18  event->Signal();
19}
20
21void PostAndWaitForWatchdogThread(base::WaitableEvent* event) {
22  WatchDogThread::PostDelayedTask(
23      FROM_HERE,
24      base::Bind(&OnThreadWatcherTask, event),
25      base::TimeDelta::FromSeconds(0));
26
27  EXPECT_TRUE(event->TimedWait(base::TimeDelta::FromSeconds(1)));
28}
29
30void NotifyApplicationStateChange(base::android::ApplicationState state) {
31  base::WaitableEvent watchdog_thread_event(false, false);
32
33  base::android::ApplicationStatusListener::NotifyApplicationStateChange(state);
34  base::RunLoop().RunUntilIdle();
35
36  PostAndWaitForWatchdogThread(&watchdog_thread_event);
37}
38
39}  // namespace
40
41TEST(ThreadWatcherAndroidTest, ApplicationStatusNotification) {
42  // Do not delay the ThreadWatcherList initialization for this test.
43  ThreadWatcherList::g_initialize_delay_seconds = 0;
44
45  base::MessageLoopForUI message_loop_for_ui;
46  content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop_for_ui);
47
48
49  scoped_ptr<WatchDogThread> watchdog_thread_(new WatchDogThread());
50  watchdog_thread_->Start();
51
52  EXPECT_FALSE(ThreadWatcherList::g_thread_watcher_list_);
53
54
55  // Register, and notify the application has just started,
56  // and ensure the thread watcher list is created.
57  ThreadWatcherAndroid::RegisterApplicationStatusListener();
58  ThreadWatcherList::StartWatchingAll(*CommandLine::ForCurrentProcess());
59  NotifyApplicationStateChange(
60      base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES);
61  EXPECT_TRUE(ThreadWatcherList::g_thread_watcher_list_);
62
63  // Notify the application has been stopped, and ensure the thread watcher list
64  // has been destroyed.
65  NotifyApplicationStateChange(
66      base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES);
67  EXPECT_FALSE(ThreadWatcherList::g_thread_watcher_list_);
68
69  // And again the last transition, STOPPED -> STARTED.
70  NotifyApplicationStateChange(
71      base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES);
72  EXPECT_TRUE(ThreadWatcherList::g_thread_watcher_list_);
73}
74