| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/shell_integration_linux.h" | 5 #include "chrome/browser/shell_integration_linux.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cstdlib> | 10 #include <cstdlib> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/base_paths.h" | 14 #include "base/base_paths.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/environment.h" | 16 #include "base/environment.h" |
| 17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 18 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
| 19 #include "base/files/scoped_temp_dir.h" | 19 #include "base/files/scoped_temp_dir.h" |
| 20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/message_loop/message_loop.h" | |
| 22 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
| 23 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
| 25 #include "base/test/scoped_path_override.h" | 24 #include "base/test/scoped_path_override.h" |
| 26 #include "chrome/common/chrome_constants.h" | 25 #include "chrome/common/chrome_constants.h" |
| 27 #include "content/public/test/test_browser_thread.h" | 26 #include "content/public/test/test_browser_thread_bundle.h" |
| 28 #include "testing/gmock/include/gmock/gmock.h" | 27 #include "testing/gmock/include/gmock/gmock.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 30 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 31 | 30 |
| 32 using content::BrowserThread; | |
| 33 using ::testing::ElementsAre; | 31 using ::testing::ElementsAre; |
| 34 | 32 |
| 35 namespace shell_integration_linux { | 33 namespace shell_integration_linux { |
| 36 | 34 |
| 37 namespace { | 35 namespace { |
| 38 | 36 |
| 39 // Provides mock environment variables values based on a stored map. | 37 // Provides mock environment variables values based on a stored map. |
| 40 class MockEnvironment : public base::Environment { | 38 class MockEnvironment : public base::Environment { |
| 41 public: | 39 public: |
| 42 MockEnvironment() {} | 40 MockEnvironment() {} |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 int bytes_written = base::WriteFile(path, str.data(), str.size()); | 87 int bytes_written = base::WriteFile(path, str.data(), str.size()); |
| 90 if (bytes_written < 0) | 88 if (bytes_written < 0) |
| 91 return false; | 89 return false; |
| 92 | 90 |
| 93 return static_cast<size_t>(bytes_written) == str.size(); | 91 return static_cast<size_t>(bytes_written) == str.size(); |
| 94 } | 92 } |
| 95 | 93 |
| 96 } // namespace | 94 } // namespace |
| 97 | 95 |
| 98 TEST(ShellIntegrationTest, GetDataWriteLocation) { | 96 TEST(ShellIntegrationTest, GetDataWriteLocation) { |
| 99 base::MessageLoop message_loop; | 97 content::TestBrowserThreadBundle test_browser_thread_bundle; |
| 100 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop); | |
| 101 | 98 |
| 102 // Test that it returns $XDG_DATA_HOME. | 99 // Test that it returns $XDG_DATA_HOME. |
| 103 { | 100 { |
| 104 MockEnvironment env; | 101 MockEnvironment env; |
| 105 base::ScopedPathOverride home_override(base::DIR_HOME, | 102 base::ScopedPathOverride home_override(base::DIR_HOME, |
| 106 base::FilePath("/home/user"), | 103 base::FilePath("/home/user"), |
| 107 true /* absolute? */, | 104 true /* absolute? */, |
| 108 false /* create? */); | 105 false /* create? */); |
| 109 env.Set("XDG_DATA_HOME", "/user/path"); | 106 env.Set("XDG_DATA_HOME", "/user/path"); |
| 110 base::FilePath path = GetDataWriteLocation(&env); | 107 base::FilePath path = GetDataWriteLocation(&env); |
| 111 EXPECT_EQ("/user/path", path.value()); | 108 EXPECT_EQ("/user/path", path.value()); |
| 112 } | 109 } |
| 113 | 110 |
| 114 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share. | 111 // Test that $XDG_DATA_HOME falls back to $HOME/.local/share. |
| 115 { | 112 { |
| 116 MockEnvironment env; | 113 MockEnvironment env; |
| 117 base::ScopedPathOverride home_override(base::DIR_HOME, | 114 base::ScopedPathOverride home_override(base::DIR_HOME, |
| 118 base::FilePath("/home/user"), | 115 base::FilePath("/home/user"), |
| 119 true /* absolute? */, | 116 true /* absolute? */, |
| 120 false /* create? */); | 117 false /* create? */); |
| 121 base::FilePath path = GetDataWriteLocation(&env); | 118 base::FilePath path = GetDataWriteLocation(&env); |
| 122 EXPECT_EQ("/home/user/.local/share", path.value()); | 119 EXPECT_EQ("/home/user/.local/share", path.value()); |
| 123 } | 120 } |
| 124 } | 121 } |
| 125 | 122 |
| 126 TEST(ShellIntegrationTest, GetDataSearchLocations) { | 123 TEST(ShellIntegrationTest, GetDataSearchLocations) { |
| 127 base::MessageLoop message_loop; | 124 content::TestBrowserThreadBundle test_browser_thread_bundle; |
| 128 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop); | |
| 129 | 125 |
| 130 // Test that it returns $XDG_DATA_HOME + $XDG_DATA_DIRS. | 126 // Test that it returns $XDG_DATA_HOME + $XDG_DATA_DIRS. |
| 131 { | 127 { |
| 132 MockEnvironment env; | 128 MockEnvironment env; |
| 133 base::ScopedPathOverride home_override(base::DIR_HOME, | 129 base::ScopedPathOverride home_override(base::DIR_HOME, |
| 134 base::FilePath("/home/user"), | 130 base::FilePath("/home/user"), |
| 135 true /* absolute? */, | 131 true /* absolute? */, |
| 136 false /* create? */); | 132 false /* create? */); |
| 137 env.Set("XDG_DATA_HOME", "/user/path"); | 133 env.Set("XDG_DATA_HOME", "/user/path"); |
| 138 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2"); | 134 env.Set("XDG_DATA_DIRS", "/system/path/1:/system/path/2"); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 } | 183 } |
| 188 } | 184 } |
| 189 | 185 |
| 190 TEST(ShellIntegrationTest, GetExistingShortcutLocations) { | 186 TEST(ShellIntegrationTest, GetExistingShortcutLocations) { |
| 191 base::FilePath kProfilePath("Profile 1"); | 187 base::FilePath kProfilePath("Profile 1"); |
| 192 const char kExtensionId[] = "test_extension"; | 188 const char kExtensionId[] = "test_extension"; |
| 193 const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop"; | 189 const char kTemplateFilename[] = "chrome-test_extension-Profile_1.desktop"; |
| 194 base::FilePath kTemplateFilepath(kTemplateFilename); | 190 base::FilePath kTemplateFilepath(kTemplateFilename); |
| 195 const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true"; | 191 const char kNoDisplayDesktopFile[] = "[Desktop Entry]\nNoDisplay=true"; |
| 196 | 192 |
| 197 base::MessageLoop message_loop; | 193 content::TestBrowserThreadBundle test_browser_thread_bundle; |
| 198 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop); | |
| 199 | 194 |
| 200 // No existing shortcuts. | 195 // No existing shortcuts. |
| 201 { | 196 { |
| 202 MockEnvironment env; | 197 MockEnvironment env; |
| 203 web_app::ShortcutLocations result = | 198 web_app::ShortcutLocations result = |
| 204 GetExistingShortcutLocations(&env, kProfilePath, kExtensionId); | 199 GetExistingShortcutLocations(&env, kProfilePath, kExtensionId); |
| 205 EXPECT_FALSE(result.on_desktop); | 200 EXPECT_FALSE(result.on_desktop); |
| 206 EXPECT_EQ(web_app::APP_MENU_LOCATION_NONE, | 201 EXPECT_EQ(web_app::APP_MENU_LOCATION_NONE, |
| 207 result.applications_menu_location); | 202 result.applications_menu_location); |
| 208 | 203 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 EXPECT_FALSE(result.in_quick_launch_bar); | 285 EXPECT_FALSE(result.in_quick_launch_bar); |
| 291 } | 286 } |
| 292 } | 287 } |
| 293 | 288 |
| 294 TEST(ShellIntegrationTest, GetExistingShortcutContents) { | 289 TEST(ShellIntegrationTest, GetExistingShortcutContents) { |
| 295 const char kTemplateFilename[] = "shortcut-test.desktop"; | 290 const char kTemplateFilename[] = "shortcut-test.desktop"; |
| 296 base::FilePath kTemplateFilepath(kTemplateFilename); | 291 base::FilePath kTemplateFilepath(kTemplateFilename); |
| 297 const char kTestData1[] = "a magical testing string"; | 292 const char kTestData1[] = "a magical testing string"; |
| 298 const char kTestData2[] = "a different testing string"; | 293 const char kTestData2[] = "a different testing string"; |
| 299 | 294 |
| 300 base::MessageLoop message_loop; | 295 content::TestBrowserThreadBundle test_browser_thread_bundle; |
| 301 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop); | |
| 302 | 296 |
| 303 // Test that it searches $XDG_DATA_HOME/applications. | 297 // Test that it searches $XDG_DATA_HOME/applications. |
| 304 { | 298 { |
| 305 base::ScopedTempDir temp_dir; | 299 base::ScopedTempDir temp_dir; |
| 306 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 300 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 307 | 301 |
| 308 MockEnvironment env; | 302 MockEnvironment env; |
| 309 env.Set("XDG_DATA_HOME", temp_dir.GetPath().value()); | 303 env.Set("XDG_DATA_HOME", temp_dir.GetPath().value()); |
| 310 // Create a file in a non-applications directory. This should be ignored. | 304 // Create a file in a non-applications directory. This should be ignored. |
| 311 ASSERT_TRUE( | 305 ASSERT_TRUE( |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 EXPECT_EQ(base::FilePath("chrome-extensionid-Profile_Name_.desktop"), | 386 EXPECT_EQ(base::FilePath("chrome-extensionid-Profile_Name_.desktop"), |
| 393 GetExtensionShortcutFilename(kProfilePath, kExtensionId)); | 387 GetExtensionShortcutFilename(kProfilePath, kExtensionId)); |
| 394 } | 388 } |
| 395 | 389 |
| 396 TEST(ShellIntegrationTest, GetExistingProfileShortcutFilenames) { | 390 TEST(ShellIntegrationTest, GetExistingProfileShortcutFilenames) { |
| 397 base::FilePath kProfilePath("a/b/c/Profile Name?"); | 391 base::FilePath kProfilePath("a/b/c/Profile Name?"); |
| 398 const char kApp1Filename[] = "chrome-extension1-Profile_Name_.desktop"; | 392 const char kApp1Filename[] = "chrome-extension1-Profile_Name_.desktop"; |
| 399 const char kApp2Filename[] = "chrome-extension2-Profile_Name_.desktop"; | 393 const char kApp2Filename[] = "chrome-extension2-Profile_Name_.desktop"; |
| 400 const char kUnrelatedAppFilename[] = "chrome-extension-Other_Profile.desktop"; | 394 const char kUnrelatedAppFilename[] = "chrome-extension-Other_Profile.desktop"; |
| 401 | 395 |
| 402 base::MessageLoop message_loop; | 396 content::TestBrowserThreadBundle test_browser_thread_bundle; |
| 403 content::TestBrowserThread file_thread(BrowserThread::FILE, &message_loop); | |
| 404 | 397 |
| 405 base::ScopedTempDir temp_dir; | 398 base::ScopedTempDir temp_dir; |
| 406 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 399 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 407 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kApp1Filename))); | 400 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kApp1Filename))); |
| 408 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kApp2Filename))); | 401 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kApp2Filename))); |
| 409 // This file should not be returned in the results. | 402 // This file should not be returned in the results. |
| 410 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kUnrelatedAppFilename))); | 403 ASSERT_TRUE(WriteEmptyFile(temp_dir.GetPath().Append(kUnrelatedAppFilename))); |
| 411 std::vector<base::FilePath> paths = | 404 std::vector<base::FilePath> paths = |
| 412 GetExistingProfileShortcutFilenames(kProfilePath, temp_dir.GetPath()); | 405 GetExistingProfileShortcutFilenames(kProfilePath, temp_dir.GetPath()); |
| 413 // Path order is arbitrary. Sort the output for consistency. | 406 // Path order is arbitrary. Sort the output for consistency. |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 EXPECT_EQ("baR", internal::GetProgramClassClass(command_line, "foo.desktop")); | 656 EXPECT_EQ("baR", internal::GetProgramClassClass(command_line, "foo.desktop")); |
| 664 | 657 |
| 665 command_line = base::CommandLine(base::FilePath()); | 658 command_line = base::CommandLine(base::FilePath()); |
| 666 command_line.AppendSwitchASCII("user-data-dir", "/tmp/baz"); | 659 command_line.AppendSwitchASCII("user-data-dir", "/tmp/baz"); |
| 667 EXPECT_EQ("foo (/tmp/baz)", | 660 EXPECT_EQ("foo (/tmp/baz)", |
| 668 internal::GetProgramClassName(command_line, "foo.desktop")); | 661 internal::GetProgramClassName(command_line, "foo.desktop")); |
| 669 EXPECT_EQ("Foo", internal::GetProgramClassClass(command_line, "foo.desktop")); | 662 EXPECT_EQ("Foo", internal::GetProgramClassClass(command_line, "foo.desktop")); |
| 670 } | 663 } |
| 671 | 664 |
| 672 } // namespace shell_integration_linux | 665 } // namespace shell_integration_linux |
| OLD | NEW |