Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / management / management_api_browsertest.cc
1 // Copyright (c) 2012 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 "base/files/file_path.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/strings/string_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/extensions/extension_browsertest.h"
10 #include "chrome/browser/extensions/extension_function_test_utils.h"
11 #include "chrome/browser/extensions/extension_install_prompt.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/common/url_constants.h"
17 #include "content/public/test/browser_test_utils.h"
18 #include "content/public/test/test_utils.h"
19 #include "extensions/browser/api/management/management_api.h"
20 #include "extensions/browser/api/management/management_api_constants.h"
21 #include "extensions/browser/extension_host.h"
22 #include "extensions/browser/extension_prefs.h"
23 #include "extensions/browser/extension_system.h"
24 #include "extensions/browser/notification_types.h"
25 #include "extensions/common/test_util.h"
26 #include "extensions/test/extension_test_message_listener.h"
27
28 namespace keys = extension_management_api_constants;
29 namespace util = extension_function_test_utils;
30
31 namespace extensions {
32
33 class ExtensionManagementApiBrowserTest : public ExtensionBrowserTest {
34  protected:
35   bool CrashEnabledExtension(const std::string& extension_id) {
36     ExtensionHost* background_host =
37         ProcessManager::Get(browser()->profile())
38             ->GetBackgroundHostForExtension(extension_id);
39     if (!background_host)
40       return false;
41     content::CrashTab(background_host->host_contents());
42     return true;
43   }
44 };
45
46 // We test this here instead of in an ExtensionApiTest because normal extensions
47 // are not allowed to call the install function.
48 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, InstallEvent) {
49   ExtensionTestMessageListener listener1("ready", false);
50   ASSERT_TRUE(LoadExtension(
51       test_data_dir_.AppendASCII("management/install_event")));
52   ASSERT_TRUE(listener1.WaitUntilSatisfied());
53
54   ExtensionTestMessageListener listener2("got_event", false);
55   ASSERT_TRUE(LoadExtension(
56       test_data_dir_.AppendASCII("api_test/management/enabled_extension")));
57   ASSERT_TRUE(listener2.WaitUntilSatisfied());
58 }
59
60 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, LaunchApp) {
61   ExtensionTestMessageListener listener1("app_launched", false);
62   ExtensionTestMessageListener listener2("got_expected_error", false);
63   ASSERT_TRUE(LoadExtension(
64       test_data_dir_.AppendASCII("management/simple_extension")));
65   ASSERT_TRUE(LoadExtension(
66       test_data_dir_.AppendASCII("management/packaged_app")));
67   ASSERT_TRUE(LoadExtension(
68       test_data_dir_.AppendASCII("management/launch_app")));
69   ASSERT_TRUE(listener1.WaitUntilSatisfied());
70   ASSERT_TRUE(listener2.WaitUntilSatisfied());
71 }
72
73 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
74                        LaunchAppFromBackground) {
75   ExtensionTestMessageListener listener1("success", false);
76   ASSERT_TRUE(LoadExtension(
77       test_data_dir_.AppendASCII("management/packaged_app")));
78   ASSERT_TRUE(LoadExtension(
79       test_data_dir_.AppendASCII("management/launch_app_from_background")));
80   ASSERT_TRUE(listener1.WaitUntilSatisfied());
81 }
82
83 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
84                        SelfUninstall) {
85   ExtensionTestMessageListener listener1("success", false);
86   ASSERT_TRUE(LoadExtension(
87       test_data_dir_.AppendASCII("management/self_uninstall_helper")));
88   ASSERT_TRUE(LoadExtension(
89       test_data_dir_.AppendASCII("management/self_uninstall")));
90   ASSERT_TRUE(listener1.WaitUntilSatisfied());
91 }
92
93 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
94                        SelfUninstallNoPermissions) {
95   ExtensionTestMessageListener listener1("success", false);
96   ASSERT_TRUE(LoadExtension(
97       test_data_dir_.AppendASCII("management/self_uninstall_helper")));
98   ASSERT_TRUE(LoadExtension(
99       test_data_dir_.AppendASCII("management/self_uninstall_noperm")));
100   ASSERT_TRUE(listener1.WaitUntilSatisfied());
101 }
102
103 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
104                        GetSelfNoPermissions) {
105   ExtensionTestMessageListener listener1("success", false);
106   ASSERT_TRUE(LoadExtension(
107       test_data_dir_.AppendASCII("management/get_self")));
108   ASSERT_TRUE(listener1.WaitUntilSatisfied());
109 }
110
111 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
112                        UninstallWithConfirmDialog) {
113   ExtensionService* service = ExtensionSystem::Get(browser()->profile())->
114       extension_service();
115
116   // Install an extension.
117   const Extension* extension = InstallExtension(
118       test_data_dir_.AppendASCII("api_test/management/enabled_extension"), 1);
119   ASSERT_TRUE(extension);
120
121   const std::string id = extension->id();
122
123   scoped_refptr<Extension> empty_extension(test_util::CreateEmptyExtension());
124   // Uninstall, then cancel via the confirm dialog.
125   scoped_refptr<ManagementUninstallFunction> uninstall_function(
126       new ManagementUninstallFunction());
127   uninstall_function->set_extension(empty_extension.get());
128   uninstall_function->set_user_gesture(true);
129   ManagementUninstallFunction::SetAutoConfirmForTest(false);
130
131   EXPECT_TRUE(MatchPattern(
132       util::RunFunctionAndReturnError(
133           uninstall_function.get(),
134           base::StringPrintf("[\"%s\", {\"showConfirmDialog\": true}]",
135                              id.c_str()),
136           browser()),
137       keys::kUninstallCanceledError));
138
139   // Make sure the extension wasn't uninstalled.
140   EXPECT_TRUE(service->GetExtensionById(id, false) != NULL);
141
142   // Uninstall, then accept via the confirm dialog.
143   uninstall_function = new ManagementUninstallFunction();
144   uninstall_function->set_extension(empty_extension.get());
145   ManagementUninstallFunction::SetAutoConfirmForTest(true);
146   uninstall_function->set_user_gesture(true);
147   util::RunFunctionAndReturnSingleResult(
148       uninstall_function.get(),
149       base::StringPrintf("[\"%s\", {\"showConfirmDialog\": true}]", id.c_str()),
150       browser());
151
152   // Make sure the extension was uninstalled.
153   EXPECT_TRUE(service->GetExtensionById(id, false) == NULL);
154 }
155
156 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
157                        CreateAppShortcutConfirmDialog) {
158   const Extension* app = InstallExtension(
159       test_data_dir_.AppendASCII("api_test/management/packaged_app"), 1);
160   ASSERT_TRUE(app);
161
162   const std::string app_id = app->id();
163
164   scoped_refptr<ManagementCreateAppShortcutFunction> create_shortcut_function(
165       new ManagementCreateAppShortcutFunction());
166   create_shortcut_function->set_user_gesture(true);
167   ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true);
168   util::RunFunctionAndReturnSingleResult(
169       create_shortcut_function.get(),
170       base::StringPrintf("[\"%s\"]", app_id.c_str()),
171       browser());
172
173   create_shortcut_function = new ManagementCreateAppShortcutFunction();
174   create_shortcut_function->set_user_gesture(true);
175   ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(false);
176   EXPECT_TRUE(MatchPattern(
177       util::RunFunctionAndReturnError(
178           create_shortcut_function.get(),
179           base::StringPrintf("[\"%s\"]", app_id.c_str()),
180           browser()),
181       keys::kCreateShortcutCanceledError));
182 }
183
184 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest,
185                        GetAllIncludesTerminated) {
186   // Load an extension with a background page, so that we know it has a process
187   // running.
188   ExtensionTestMessageListener listener("ready", false);
189   const Extension* extension = LoadExtension(
190       test_data_dir_.AppendASCII("management/install_event"));
191   ASSERT_TRUE(extension);
192   ASSERT_TRUE(listener.WaitUntilSatisfied());
193
194   // The management API should list this extension.
195   scoped_refptr<ManagementGetAllFunction> function =
196       new ManagementGetAllFunction();
197   scoped_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult(
198       function.get(), "[]", browser()));
199   base::ListValue* list;
200   ASSERT_TRUE(result->GetAsList(&list));
201   EXPECT_EQ(1U, list->GetSize());
202
203   // And it should continue to do so even after it crashes.
204   ASSERT_TRUE(CrashEnabledExtension(extension->id()));
205
206   function = new ManagementGetAllFunction();
207   result.reset(util::RunFunctionAndReturnSingleResult(
208       function.get(), "[]", browser()));
209   ASSERT_TRUE(result->GetAsList(&list));
210   EXPECT_EQ(1U, list->GetSize());
211 }
212
213 class ExtensionManagementApiEscalationTest :
214     public ExtensionManagementApiBrowserTest {
215  protected:
216   // The id of the permissions escalation test extension we use.
217   static const char kId[];
218
219   void SetUpOnMainThread() override {
220     EXPECT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
221     base::FilePath pem_path = test_data_dir_.
222         AppendASCII("permissions_increase").AppendASCII("permissions.pem");
223     base::FilePath path_v1 = PackExtensionWithOptions(
224         test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v1"),
225         scoped_temp_dir_.path().AppendASCII("permissions1.crx"),
226         pem_path,
227         base::FilePath());
228     base::FilePath path_v2 = PackExtensionWithOptions(
229         test_data_dir_.AppendASCII("permissions_increase").AppendASCII("v2"),
230         scoped_temp_dir_.path().AppendASCII("permissions2.crx"),
231         pem_path,
232         base::FilePath());
233
234     ExtensionService* service = ExtensionSystem::Get(browser()->profile())->
235         extension_service();
236
237     // Install low-permission version of the extension.
238     ASSERT_TRUE(InstallExtension(path_v1, 1));
239     EXPECT_TRUE(service->GetExtensionById(kId, false) != NULL);
240
241     // Update to a high-permission version - it should get disabled.
242     EXPECT_FALSE(UpdateExtension(kId, path_v2, -1));
243     EXPECT_TRUE(service->GetExtensionById(kId, false) == NULL);
244     EXPECT_TRUE(service->GetExtensionById(kId, true) != NULL);
245     EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())
246                     ->DidExtensionEscalatePermissions(kId));
247   }
248
249   void SetEnabled(bool enabled, bool user_gesture,
250                   const std::string& expected_error) {
251     scoped_refptr<ManagementSetEnabledFunction> function(
252         new ManagementSetEnabledFunction);
253     const char* const enabled_string = enabled ? "true" : "false";
254     if (user_gesture)
255       function->set_user_gesture(true);
256     bool response = util::RunFunction(
257         function.get(),
258         base::StringPrintf("[\"%s\", %s]", kId, enabled_string),
259         browser(),
260         util::NONE);
261     if (expected_error.empty()) {
262       EXPECT_EQ(true, response);
263     } else {
264       EXPECT_TRUE(response == false);
265       EXPECT_EQ(expected_error, function->GetError());
266     }
267   }
268
269
270  private:
271   base::ScopedTempDir scoped_temp_dir_;
272 };
273
274 const char ExtensionManagementApiEscalationTest::kId[] =
275     "pgdpcfcocojkjfbgpiianjngphoopgmo";
276
277 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest,
278                        DisabledReason) {
279   scoped_refptr<ManagementGetFunction> function =
280       new ManagementGetFunction();
281   scoped_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult(
282       function.get(),
283       base::StringPrintf("[\"%s\"]", kId),
284       browser()));
285   ASSERT_TRUE(result.get() != NULL);
286   ASSERT_TRUE(result->IsType(base::Value::TYPE_DICTIONARY));
287   base::DictionaryValue* dict =
288       static_cast<base::DictionaryValue*>(result.get());
289   std::string reason;
290   EXPECT_TRUE(dict->GetStringASCII(keys::kDisabledReasonKey, &reason));
291   EXPECT_EQ(reason, std::string(keys::kDisabledReasonPermissionsIncrease));
292 }
293
294 IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest,
295                        SetEnabled) {
296   // Expect an error about no gesture.
297   SetEnabled(true, false, keys::kGestureNeededForEscalationError);
298
299   // Expect an error that user cancelled the dialog.
300   ExtensionInstallPrompt::g_auto_confirm_for_tests =
301       ExtensionInstallPrompt::CANCEL;
302   SetEnabled(true, true, keys::kUserDidNotReEnableError);
303
304   // This should succeed when user accepts dialog.  We must wait for the process
305   // to connect *and* for the channel to finish initializing before trying to
306   // crash it.  (NOTIFICATION_RENDERER_PROCESS_CREATED does not wait for the
307   // latter and can cause KillProcess to fail on Windows.)
308   content::WindowedNotificationObserver observer(
309       extensions::NOTIFICATION_EXTENSION_HOST_CREATED,
310       content::NotificationService::AllSources());
311   ExtensionInstallPrompt::g_auto_confirm_for_tests =
312       ExtensionInstallPrompt::ACCEPT;
313   SetEnabled(true, true, std::string());
314   observer.Wait();
315
316   // Crash the extension. Mock a reload by disabling and then enabling. The
317   // extension should be reloaded and enabled.
318   ASSERT_TRUE(CrashEnabledExtension(kId));
319   SetEnabled(false, true, std::string());
320   SetEnabled(true, true, std::string());
321   const Extension* extension = ExtensionSystem::Get(browser()->profile())
322       ->extension_service()->GetExtensionById(kId, false);
323   EXPECT_TRUE(extension);
324 }
325
326 }  // namespace extensions