extension_gcm_app_handler_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file.
4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_gcm_app_handler.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <vector>
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/bind.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/bind_helpers.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/command_line.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/files/file_path.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/location.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/ref_counted.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/message_loop/message_loop.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/prefs/pref_service.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/run_loop.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/values.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_service.h"
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/test_extension_service.h"
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/test_extension_system.h"
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile.h"
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/services/gcm/fake_signin_manager.h"
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/services/gcm/gcm_profile_service.h"
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/signin/signin_manager_factory.h"
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/common/pref_names.h"
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/test/base/testing_profile.h"
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/fake_gcm_app_handler.h"
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/fake_gcm_client.h"
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/fake_gcm_client_factory.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/gcm_client_factory.h"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/gcm_driver.h"
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "components/keyed_service/core/keyed_service.h"
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/browser/browser_context.h"
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/browser/browser_thread.h"
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/test/test_browser_thread_bundle.h"
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/browser/extension_system.h"
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension.h"
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/manifest.h"
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_constants.h"
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/permissions/api_permission.h"
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if !defined(OS_ANDROID)
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/api/gcm/gcm_api.h"
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_CHROMEOS)
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/user_manager.h"
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/chromeos/settings/cros_settings.h"
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/chromeos/settings/device_settings_service.h"
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace extensions {
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace {
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kTestExtensionName[] = "FooBar";
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kTestingUsername[] = "user1@example.com";
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Helper class for asynchronous waiting.
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass Waiter {
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public:
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Waiter() {}
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ~Waiter() {}
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Waits until the asynchronous operation finishes.
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void WaitUntilCompleted() {
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    run_loop_.reset(new base::RunLoop);
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    run_loop_->Run();
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Signals that the asynchronous operation finishes.
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void SignalCompleted() {
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (run_loop_ && run_loop_->running())
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      run_loop_->Quit();
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Runs until UI loop becomes idle.
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void PumpUILoop() {
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::MessageLoop::current()->RunUntilIdle();
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Runs until IO loop becomes idle.
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void PumpIOLoop() {
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::BrowserThread::PostTask(
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::BrowserThread::IO,
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&Waiter::OnIOLoopPump, base::Unretained(this)));
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    WaitUntilCompleted();
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private:
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void PumpIOLoopCompleted() {
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    SignalCompleted();
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void OnIOLoopPump() {
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::BrowserThread::PostTask(
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::BrowserThread::IO,
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&Waiter::OnIOLoopPumpCompleted, base::Unretained(this)));
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void OnIOLoopPumpCompleted() {
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    content::BrowserThread::PostTask(
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        content::BrowserThread::UI,
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&Waiter::PumpIOLoopCompleted, base::Unretained(this)));
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<base::RunLoop> run_loop_;
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DISALLOW_COPY_AND_ASSIGN(Waiter);
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass FakeExtensionGCMAppHandler : public ExtensionGCMAppHandler {
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FakeExtensionGCMAppHandler(Profile* profile, Waiter* waiter)
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      : ExtensionGCMAppHandler(profile),
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        waiter_(waiter),
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR) {
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual ~FakeExtensionGCMAppHandler() {
138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void OnMessage(
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      const std::string& app_id,
1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const gcm::GCMClient::IncomingMessage& message) OVERRIDE {
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE {
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void OnSendError(
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      const std::string& app_id,
1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE {
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void OnUnregisterCompleted(const std::string& app_id,
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                     gcm::GCMClient::Result result) OVERRIDE {
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    unregistration_result_ = result;
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    waiter_->SignalCompleted();
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result unregistration_result() const {
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return unregistration_result_;
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Waiter* waiter_;
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result unregistration_result_;
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FakeExtensionGCMAppHandler);
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass ExtensionGCMAppHandlerTest : public testing::Test {
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static KeyedService* BuildGCMProfileService(
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      content::BrowserContext* context) {
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return new gcm::GCMProfileService(
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        Profile::FromBrowserContext(context),
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scoped_ptr<gcm::GCMClientFactory>(new gcm::FakeGCMClientFactory(
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            gcm::FakeGCMClient::NO_DELAY_START,
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            content::BrowserThread::GetMessageLoopProxyForThread(
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                content::BrowserThread::UI),
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            content::BrowserThread::GetMessageLoopProxyForThread(
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                content::BrowserThread::IO))));
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ExtensionGCMAppHandlerTest()
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      : extension_service_(NULL),
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        registration_result_(gcm::GCMClient::UNKNOWN_ERROR),
1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR) {
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual ~ExtensionGCMAppHandlerTest() {
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Overridden from test::Test:
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void SetUp() OVERRIDE {
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Make BrowserThread work in unittest.
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    thread_bundle_.reset(new content::TestBrowserThreadBundle(
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        content::TestBrowserThreadBundle::REAL_IO_THREAD));
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // This is needed to create extension service under CrOS.
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_CHROMEOS)
201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    test_user_manager_.reset(new chromeos::ScopedTestUserManager());
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Create a new profile.
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    TestingProfile::Builder builder;
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                              gcm::FakeSigninManager::Build);
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    profile_ = builder.Build();
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    signin_manager_ = static_cast<gcm::FakeSigninManager*>(
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        SigninManagerFactory::GetInstance()->GetForProfile(profile_.get()));
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Create extension service in order to uninstall the extension.
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    TestExtensionSystem* extension_system(
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile())));
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_system->CreateExtensionService(
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        CommandLine::ForCurrentProcess(), base::FilePath(), false);
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_service_ = extension_system->Get(profile())->extension_service();
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Enable GCM such that tests could be run on all channels.
220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Create GCMProfileService that talks with fake GCMClient.
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse(
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        profile(), &ExtensionGCMAppHandlerTest::BuildGCMProfileService);
225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    // Create a fake version of ExtensionGCMAppHandler.
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    gcm_app_handler_.reset(new FakeExtensionGCMAppHandler(profile(), &waiter_));
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual void TearDown() OVERRIDE {
231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_CHROMEOS)
232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    test_user_manager_.reset();
233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    waiter_.PumpUILoop();
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Returns a barebones test extension.
239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<Extension> CreateExtension() {
240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_WIN)
241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::FilePath path(FILE_PATH_LITERAL("c:\\foo"));
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#elif defined(OS_POSIX)
243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::FilePath path(FILE_PATH_LITERAL("/foo"));
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::DictionaryValue manifest;
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    manifest.SetString(manifest_keys::kVersion, "1.0.0.0");
248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    manifest.SetString(manifest_keys::kName, kTestExtensionName);
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::ListValue* permission_list = new base::ListValue;
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    permission_list->Append(base::Value::CreateStringValue("gcm"));
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    manifest.Set(manifest_keys::kPermissions, permission_list);
252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    std::string error;
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_refptr<Extension> extension = Extension::Create(
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        path.AppendASCII(kTestExtensionName),
256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        Manifest::INVALID_LOCATION,
257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        manifest,
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        Extension::NO_FLAGS,
259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        &error);
260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    EXPECT_TRUE(extension.get()) << error;
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_TRUE(
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension->permissions_data()->HasAPIPermission(APIPermission::kGcm));
263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return extension;
265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void LoadExtension(const Extension* extension) {
268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_service_->AddExtension(extension);
269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void DisableExtension(const Extension* extension) {
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_service_->DisableExtension(
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        extension->id(), Extension::DISABLE_USER_ACTION);
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void EnableExtension(const Extension* extension) {
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_service_->EnableExtension(extension->id());
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void UninstallExtension(const Extension* extension) {
281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    extension_service_->UninstallExtension(extension->id(), false, NULL);
282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void SignIn(const std::string& username) {
285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    signin_manager_->SignIn(username);
286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    waiter_.PumpIOLoop();
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void SignOut() {
290c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    signin_manager_->SignOut();
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    waiter_.PumpIOLoop();
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void Register(const std::string& app_id,
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                const std::vector<std::string>& sender_ids) {
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GetGCMDriver()->Register(
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        app_id,
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        sender_ids,
299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        base::Bind(&ExtensionGCMAppHandlerTest::RegisterCompleted,
300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                   base::Unretained(this)));
301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void RegisterCompleted(const std::string& registration_id,
3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                         gcm::GCMClient::Result result) {
305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    registration_result_ = result;
306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    waiter_.SignalCompleted();
307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gcm::GCMDriver* GetGCMDriver() const {
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return gcm::GCMProfileServiceFactory::GetForProfile(profile())->driver();
311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
312c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
313c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool HasAppHandlers(const std::string& app_id) const {
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GetGCMDriver()->app_handlers().count(app_id);
315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
316c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Profile* profile() const { return profile_.get(); }
318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Waiter* waiter() { return &waiter_; }
319c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FakeExtensionGCMAppHandler* gcm_app_handler() const {
320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return gcm_app_handler_.get();
321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result registration_result() const {
3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return registration_result_;
3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result unregistration_result() const {
326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return unregistration_result_;
327c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
328c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
329c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
330c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_;
331c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<TestingProfile> profile_;
332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ExtensionService* extension_service_;  // Not owned.
333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  gcm::FakeSigninManager* signin_manager_;  // Not owned.
334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // This is needed to create extension service under CrOS.
336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_CHROMEOS)
337c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  chromeos::ScopedTestCrosSettings test_cros_settings_;
339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
342c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Waiter waiter_;
343c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<FakeExtensionGCMAppHandler> gcm_app_handler_;
3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result registration_result_;
3455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  gcm::GCMClient::Result unregistration_result_;
346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
347c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ExtensionGCMAppHandlerTest);
348c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(ExtensionGCMAppHandlerTest, AddAndRemoveAppHandler) {
351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<Extension> extension(CreateExtension());
352c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
353c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // App handler is added when extension is loaded.
354c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LoadExtension(extension);
355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->PumpUILoop();
356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(HasAppHandlers(extension->id()));
357c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
358c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // App handler is removed when extension is unloaded.
359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DisableExtension(extension);
360c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->PumpUILoop();
361c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(HasAppHandlers(extension->id()));
362c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // App handler is added when extension is reloaded.
364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EnableExtension(extension);
365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->PumpUILoop();
366c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(HasAppHandlers(extension->id()));
367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // App handler is removed when extension is uninstalled.
369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  UninstallExtension(extension);
370c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->PumpUILoop();
371c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(HasAppHandlers(extension->id()));
372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
373c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
374c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(ExtensionGCMAppHandlerTest, UnregisterOnExtensionUninstall) {
375c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<Extension> extension(CreateExtension());
376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LoadExtension(extension);
377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
378c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Sign-in is needed for registration.
379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SignIn(kTestingUsername);
380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Kick off registration.
382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<std::string> sender_ids;
383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  sender_ids.push_back("sender1");
384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Register(extension->id(), sender_ids);
385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->WaitUntilCompleted();
3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(gcm::GCMClient::SUCCESS, registration_result());
387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Add another app handler in order to prevent the GCM service from being
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // stopped when the extension is uninstalled. This is needed because otherwise
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // we are not able to receive the unregistration result.
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetGCMDriver()->AddAppHandler("Foo", gcm_app_handler());
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Unregistration should be triggered when the extension is uninstalled.
394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  UninstallExtension(extension);
395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  waiter()->WaitUntilCompleted();
3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(gcm::GCMClient::SUCCESS,
3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            gcm_app_handler()->unregistration_result());
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Clean up.
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GetGCMDriver()->RemoveAppHandler("Foo");
401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
403c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace extensions
404