| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/note_taking_helper.h" | 5 #include "chrome/browser/chromeos/note_taking_helper.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "ash/common/ash_switches.h" | 9 #include "ash/common/ash_switches.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 23 #include "chrome/test/base/browser_with_test_window_test.h" | 23 #include "chrome/test/base/browser_with_test_window_test.h" |
| 24 #include "chrome/test/base/testing_browser_process.h" | 24 #include "chrome/test/base/testing_browser_process.h" |
| 25 #include "chrome/test/base/testing_profile_manager.h" | 25 #include "chrome/test/base/testing_profile_manager.h" |
| 26 #include "chromeos/dbus/dbus_thread_manager.h" | 26 #include "chromeos/dbus/dbus_thread_manager.h" |
| 27 #include "chromeos/dbus/fake_session_manager_client.h" | 27 #include "chromeos/dbus/fake_session_manager_client.h" |
| 28 #include "components/arc/arc_bridge_service.h" | 28 #include "components/arc/arc_bridge_service.h" |
| 29 #include "components/arc/arc_service_manager.h" | 29 #include "components/arc/arc_service_manager.h" |
| 30 #include "components/arc/common/intent_helper.mojom.h" | 30 #include "components/arc/common/intent_helper.mojom.h" |
| 31 #include "components/arc/test/fake_intent_helper_instance.h" | 31 #include "components/arc/test/fake_intent_helper_instance.h" |
| 32 #include "components/crx_file/id_util.h" |
| 32 #include "content/public/browser/notification_service.h" | 33 #include "content/public/browser/notification_service.h" |
| 33 #include "content/public/browser/notification_source.h" | 34 #include "content/public/browser/notification_source.h" |
| 34 #include "extensions/common/api/app_runtime.h" | 35 #include "extensions/common/api/app_runtime.h" |
| 35 #include "extensions/common/extension_builder.h" | 36 #include "extensions/common/extension_builder.h" |
| 36 #include "extensions/common/extension_id.h" | 37 #include "extensions/common/extension_id.h" |
| 37 #include "extensions/common/value_builder.h" | 38 #include "extensions/common/value_builder.h" |
| 38 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 39 | 40 |
| 40 namespace app_runtime = extensions::api::app_runtime; | 41 namespace app_runtime = extensions::api::app_runtime; |
| 41 | 42 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 profile()->GetPrefs()->SetBoolean(prefs::kArcEnabled, flags & ENABLE_ARC); | 186 profile()->GetPrefs()->SetBoolean(prefs::kArcEnabled, flags & ENABLE_ARC); |
| 186 NoteTakingHelper::Initialize(); | 187 NoteTakingHelper::Initialize(); |
| 187 NoteTakingHelper::Get()->set_launch_chrome_app_callback_for_test(base::Bind( | 188 NoteTakingHelper::Get()->set_launch_chrome_app_callback_for_test(base::Bind( |
| 188 &NoteTakingHelperTest::LaunchChromeApp, base::Unretained(this))); | 189 &NoteTakingHelperTest::LaunchChromeApp, base::Unretained(this))); |
| 189 } | 190 } |
| 190 | 191 |
| 191 // Creates an extension. | 192 // Creates an extension. |
| 192 scoped_refptr<const extensions::Extension> CreateExtension( | 193 scoped_refptr<const extensions::Extension> CreateExtension( |
| 193 const extensions::ExtensionId& id, | 194 const extensions::ExtensionId& id, |
| 194 const std::string& name) { | 195 const std::string& name) { |
| 196 return CreateExtension(id, name, nullptr); |
| 197 } |
| 198 scoped_refptr<const extensions::Extension> CreateExtension( |
| 199 const extensions::ExtensionId& id, |
| 200 const std::string& name, |
| 201 std::unique_ptr<base::Value> action_handlers) { |
| 195 std::unique_ptr<base::DictionaryValue> manifest = | 202 std::unique_ptr<base::DictionaryValue> manifest = |
| 196 extensions::DictionaryBuilder() | 203 extensions::DictionaryBuilder() |
| 197 .Set("name", name) | 204 .Set("name", name) |
| 198 .Set("version", "1.0") | 205 .Set("version", "1.0") |
| 199 .Set("manifest_version", 2) | 206 .Set("manifest_version", 2) |
| 200 .Set("app", | 207 .Set("app", |
| 201 extensions::DictionaryBuilder() | 208 extensions::DictionaryBuilder() |
| 202 .Set("background", | 209 .Set("background", |
| 203 extensions::DictionaryBuilder() | 210 extensions::DictionaryBuilder() |
| 204 .Set("scripts", extensions::ListBuilder() | 211 .Set("scripts", extensions::ListBuilder() |
| 205 .Append("background.js") | 212 .Append("background.js") |
| 206 .Build()) | 213 .Build()) |
| 207 .Build()) | 214 .Build()) |
| 208 .Build()) | 215 .Build()) |
| 209 .Build(); | 216 .Build(); |
| 217 |
| 218 if (action_handlers) |
| 219 manifest->Set("action_handlers", std::move(action_handlers)); |
| 220 |
| 210 return extensions::ExtensionBuilder() | 221 return extensions::ExtensionBuilder() |
| 211 .SetManifest(std::move(manifest)) | 222 .SetManifest(std::move(manifest)) |
| 212 .SetID(id) | 223 .SetID(id) |
| 213 .Build(); | 224 .Build(); |
| 214 } | 225 } |
| 215 | 226 |
| 216 // Initializes extensions-related objects for |profile|. Tests only need to | 227 // Initializes extensions-related objects for |profile|. Tests only need to |
| 217 // call this if they create additional profiles of their own. | 228 // call this if they create additional profiles of their own. |
| 218 void InitExtensionService(Profile* profile) { | 229 void InitExtensionService(Profile* profile) { |
| 219 extensions::TestExtensionSystem* extension_system = | 230 extensions::TestExtensionSystem* extension_system = |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 apps = helper()->GetAvailableApps(profile()); | 325 apps = helper()->GetAvailableApps(profile()); |
| 315 ASSERT_EQ(2u, apps.size()); | 326 ASSERT_EQ(2u, apps.size()); |
| 316 EXPECT_EQ( | 327 EXPECT_EQ( |
| 317 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), | 328 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), |
| 318 GetAppString(apps[0])); | 329 GetAppString(apps[0])); |
| 319 EXPECT_EQ( | 330 EXPECT_EQ( |
| 320 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, false), | 331 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, false), |
| 321 GetAppString(apps[1])); | 332 GetAppString(apps[1])); |
| 322 | 333 |
| 323 // Now install a random extension and check that it's ignored. | 334 // Now install a random extension and check that it's ignored. |
| 324 const extensions::ExtensionId kOtherId = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | 335 const extensions::ExtensionId kOtherId = crx_file::id_util::GenerateId("a"); |
| 325 const std::string kOtherName = "Some Other App"; | 336 const std::string kOtherName = "Some Other App"; |
| 326 auto other_extension = CreateExtension(kOtherId, kOtherName); | 337 auto other_extension = CreateExtension(kOtherId, kOtherName); |
| 327 InstallExtension(other_extension.get(), profile()); | 338 InstallExtension(other_extension.get(), profile()); |
| 328 apps = helper()->GetAvailableApps(profile()); | 339 apps = helper()->GetAvailableApps(profile()); |
| 329 ASSERT_EQ(2u, apps.size()); | 340 ASSERT_EQ(2u, apps.size()); |
| 330 EXPECT_EQ( | 341 EXPECT_EQ( |
| 331 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), | 342 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), |
| 332 GetAppString(apps[0])); | 343 GetAppString(apps[0])); |
| 333 EXPECT_EQ( | 344 EXPECT_EQ( |
| 334 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, false), | 345 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, false), |
| 335 GetAppString(apps[1])); | 346 GetAppString(apps[1])); |
| 336 | 347 |
| 337 // Mark the prod version as preferred. | 348 // Mark the prod version as preferred. |
| 338 helper()->SetPreferredApp(profile(), NoteTakingHelper::kProdKeepExtensionId); | 349 helper()->SetPreferredApp(profile(), NoteTakingHelper::kProdKeepExtensionId); |
| 339 apps = helper()->GetAvailableApps(profile()); | 350 apps = helper()->GetAvailableApps(profile()); |
| 340 ASSERT_EQ(2u, apps.size()); | 351 ASSERT_EQ(2u, apps.size()); |
| 341 EXPECT_EQ( | 352 EXPECT_EQ( |
| 342 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), | 353 GetAppString(NoteTakingHelper::kDevKeepExtensionId, kDevName, false), |
| 343 GetAppString(apps[0])); | 354 GetAppString(apps[0])); |
| 344 EXPECT_EQ( | 355 EXPECT_EQ( |
| 345 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, true), | 356 GetAppString(NoteTakingHelper::kProdKeepExtensionId, kProdName, true), |
| 346 GetAppString(apps[1])); | 357 GetAppString(apps[1])); |
| 347 } | 358 } |
| 348 | 359 |
| 360 // Verify the note helper detects apps with "new_note" "action_handler" manifest |
| 361 // entries. |
| 362 TEST_F(NoteTakingHelperTest, CustomChromeApps) { |
| 363 Init(ENABLE_PALETTE); |
| 364 |
| 365 const extensions::ExtensionId kNewNoteId = crx_file::id_util::GenerateId("a"); |
| 366 const extensions::ExtensionId kEmptyArrayId = |
| 367 crx_file::id_util::GenerateId("b"); |
| 368 const extensions::ExtensionId kEmptyId = crx_file::id_util::GenerateId("c"); |
| 369 const std::string kName = "Some App"; |
| 370 |
| 371 // "action_handlers": ["new_note"] |
| 372 auto has_new_note = CreateExtension( |
| 373 kNewNoteId, kName, |
| 374 extensions::ListBuilder() |
| 375 .Append(app_runtime::ToString(app_runtime::ACTION_TYPE_NEW_NOTE)) |
| 376 .Build()); |
| 377 InstallExtension(has_new_note.get(), profile()); |
| 378 // "action_handlers": [] |
| 379 auto empty_array = |
| 380 CreateExtension(kEmptyArrayId, kName, extensions::ListBuilder().Build()); |
| 381 InstallExtension(empty_array.get(), profile()); |
| 382 // (no action handler entry) |
| 383 auto none = CreateExtension(kEmptyId, kName); |
| 384 InstallExtension(none.get(), profile()); |
| 385 |
| 386 // Only the "new_note" extension is returned from GetAvailableApps. |
| 387 std::vector<NoteTakingAppInfo> apps = helper()->GetAvailableApps(profile()); |
| 388 ASSERT_EQ(1u, apps.size()); |
| 389 EXPECT_EQ(GetAppString(kNewNoteId, kName, false), GetAppString(apps[0])); |
| 390 } |
| 391 |
| 392 TEST_F(NoteTakingHelperTest, WhitelistedAndCustomAppsShowOnlyOnce) { |
| 393 Init(ENABLE_PALETTE); |
| 394 |
| 395 auto extension = CreateExtension( |
| 396 NoteTakingHelper::kProdKeepExtensionId, "Keep", |
| 397 extensions::ListBuilder() |
| 398 .Append(app_runtime::ToString(app_runtime::ACTION_TYPE_NEW_NOTE)) |
| 399 .Build()); |
| 400 InstallExtension(extension.get(), profile()); |
| 401 |
| 402 std::vector<NoteTakingAppInfo> apps = helper()->GetAvailableApps(profile()); |
| 403 ASSERT_EQ(1u, apps.size()); |
| 404 EXPECT_EQ(GetAppString(NoteTakingHelper::kProdKeepExtensionId, "Keep", false), |
| 405 GetAppString(apps[0])); |
| 406 } |
| 407 |
| 349 TEST_F(NoteTakingHelperTest, LaunchChromeApp) { | 408 TEST_F(NoteTakingHelperTest, LaunchChromeApp) { |
| 350 Init(ENABLE_PALETTE); | 409 Init(ENABLE_PALETTE); |
| 351 auto extension = | 410 auto extension = |
| 352 CreateExtension(NoteTakingHelper::kProdKeepExtensionId, "Keep"); | 411 CreateExtension(NoteTakingHelper::kProdKeepExtensionId, "Keep"); |
| 353 InstallExtension(extension.get(), profile()); | 412 InstallExtension(extension.get(), profile()); |
| 354 | 413 |
| 355 // Check the Chrome app is launched with the correct parameters. | 414 // Check the Chrome app is launched with the correct parameters. |
| 356 HistogramTester histogram_tester; | 415 HistogramTester histogram_tester; |
| 357 const base::FilePath kPath("/foo/bar/photo.jpg"); | 416 const base::FilePath kPath("/foo/bar/photo.jpg"); |
| 358 helper()->LaunchAppForNewNote(profile(), kPath); | 417 helper()->LaunchAppForNewNote(profile(), kPath); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 CreateExtension(NoteTakingHelper::kProdKeepExtensionId, "Keep"); | 667 CreateExtension(NoteTakingHelper::kProdKeepExtensionId, "Keep"); |
| 609 InstallExtension(keep_extension.get(), profile()); | 668 InstallExtension(keep_extension.get(), profile()); |
| 610 EXPECT_EQ(1, observer.num_updates()); | 669 EXPECT_EQ(1, observer.num_updates()); |
| 611 | 670 |
| 612 // Unloading the extension should also trigger a notification. | 671 // Unloading the extension should also trigger a notification. |
| 613 UninstallExtension(keep_extension.get(), profile()); | 672 UninstallExtension(keep_extension.get(), profile()); |
| 614 EXPECT_EQ(2, observer.num_updates()); | 673 EXPECT_EQ(2, observer.num_updates()); |
| 615 | 674 |
| 616 // Non-whitelisted apps shouldn't trigger notifications. | 675 // Non-whitelisted apps shouldn't trigger notifications. |
| 617 auto other_extension = | 676 auto other_extension = |
| 618 CreateExtension("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "Some Other App"); | 677 CreateExtension(crx_file::id_util::GenerateId("a"), "Some Other App"); |
| 619 InstallExtension(other_extension.get(), profile()); | 678 InstallExtension(other_extension.get(), profile()); |
| 620 EXPECT_EQ(2, observer.num_updates()); | 679 EXPECT_EQ(2, observer.num_updates()); |
| 621 UninstallExtension(other_extension.get(), profile()); | 680 UninstallExtension(other_extension.get(), profile()); |
| 622 EXPECT_EQ(2, observer.num_updates()); | 681 EXPECT_EQ(2, observer.num_updates()); |
| 623 | 682 |
| 624 // Add a second profile and check that it triggers notifications too. | 683 // Add a second profile and check that it triggers notifications too. |
| 625 observer.reset_num_updates(); | 684 observer.reset_num_updates(); |
| 626 const std::string kSecondProfileName = "second-profile"; | 685 const std::string kSecondProfileName = "second-profile"; |
| 627 TestingProfile* second_profile = | 686 TestingProfile* second_profile = |
| 628 profile_manager_->CreateTestingProfile(kSecondProfileName); | 687 profile_manager_->CreateTestingProfile(kSecondProfileName); |
| 629 InitExtensionService(second_profile); | 688 InitExtensionService(second_profile); |
| 630 EXPECT_EQ(0, observer.num_updates()); | 689 EXPECT_EQ(0, observer.num_updates()); |
| 631 InstallExtension(keep_extension.get(), second_profile); | 690 InstallExtension(keep_extension.get(), second_profile); |
| 632 EXPECT_EQ(1, observer.num_updates()); | 691 EXPECT_EQ(1, observer.num_updates()); |
| 633 UninstallExtension(keep_extension.get(), second_profile); | 692 UninstallExtension(keep_extension.get(), second_profile); |
| 634 EXPECT_EQ(2, observer.num_updates()); | 693 EXPECT_EQ(2, observer.num_updates()); |
| 635 profile_manager_->DeleteTestingProfile(kSecondProfileName); | 694 profile_manager_->DeleteTestingProfile(kSecondProfileName); |
| 636 } | 695 } |
| 637 | 696 |
| 638 } // namespace chromeos | 697 } // namespace chromeos |
| OLD | NEW |