| 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/android/webapk/webapk_installer.h" | 5 #include "chrome/browser/android/webapk/webapk_installer.h" |
| 6 | 6 |
| 7 #include <jni.h> | 7 #include <jni.h> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 30 #include "third_party/skia/include/core/SkBitmap.h" | 30 #include "third_party/skia/include/core/SkBitmap.h" |
| 31 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 const base::FilePath::CharType kTestDataDir[] = | 35 const base::FilePath::CharType kTestDataDir[] = |
| 36 FILE_PATH_LITERAL("chrome/test/data"); | 36 FILE_PATH_LITERAL("chrome/test/data"); |
| 37 | 37 |
| 38 // URL of mock WebAPK server. | 38 // URL of mock WebAPK server. |
| 39 const std::string kServerUrl = "/webapkserver"; | 39 const char* kServerUrl = "/webapkserver"; |
| 40 |
| 41 // Icon URL from Web Manifest. We use a random file in the test data directory. |
| 42 // Since WebApkInstaller does not try to decode the file as an image it is OK |
| 43 // that the file is not an image. |
| 44 const char* kIconUrl = "/simple.html"; |
| 40 | 45 |
| 41 // URL of file to download from the WebAPK server. We use a random file in the | 46 // URL of file to download from the WebAPK server. We use a random file in the |
| 42 // test data directory. | 47 // test data directory. |
| 43 const std::string kDownloadUrl = "/simple.html"; | 48 const char* kDownloadUrl = "/simple.html"; |
| 44 | 49 |
| 45 // The package name of the downloaded WebAPK. | 50 // The package name of the downloaded WebAPK. |
| 46 const std::string kDownloadedWebApkPackageName = "party.unicode"; | 51 const char* kDownloadedWebApkPackageName = "party.unicode"; |
| 47 | 52 |
| 48 // WebApkInstaller subclass where | 53 // WebApkInstaller subclass where |
| 49 // WebApkInstaller::StartDownloadedWebApkInstall() is stubbed out. | 54 // WebApkInstaller::StartDownloadedWebApkInstall() is stubbed out. |
| 50 class TestWebApkInstaller : public WebApkInstaller { | 55 class TestWebApkInstaller : public WebApkInstaller { |
| 51 public: | 56 public: |
| 52 TestWebApkInstaller(const ShortcutInfo& shortcut_info, | 57 TestWebApkInstaller(const ShortcutInfo& shortcut_info, |
| 53 const SkBitmap& shortcut_icon) | 58 const SkBitmap& shortcut_icon) |
| 54 : WebApkInstaller(shortcut_info, shortcut_icon) {} | 59 : WebApkInstaller(shortcut_info, shortcut_icon) {} |
| 55 | 60 |
| 56 bool StartDownloadedWebApkInstall( | 61 bool StartDownloadedWebApkInstall( |
| 57 JNIEnv* env, | 62 JNIEnv* env, |
| 58 const base::android::ScopedJavaLocalRef<jstring>& file_path, | 63 const base::android::ScopedJavaLocalRef<jstring>& file_path, |
| 59 const base::android::ScopedJavaLocalRef<jstring>& package_name) override { | 64 const base::android::ScopedJavaLocalRef<jstring>& package_name) override { |
| 60 return true; | 65 return true; |
| 61 } | 66 } |
| 62 | 67 |
| 63 private: | 68 private: |
| 64 DISALLOW_COPY_AND_ASSIGN(TestWebApkInstaller); | 69 DISALLOW_COPY_AND_ASSIGN(TestWebApkInstaller); |
| 65 }; | 70 }; |
| 66 | 71 |
| 67 // Runs the WebApkInstaller installation process and blocks till done. | 72 // Runs the WebApkInstaller installation process and blocks till done. |
| 68 class WebApkInstallerRunner { | 73 class WebApkInstallerRunner { |
| 69 public: | 74 public: |
| 70 WebApkInstallerRunner() | 75 explicit WebApkInstallerRunner(const GURL& icon_url) |
| 71 : url_request_context_getter_(new net::TestURLRequestContextGetter( | 76 : url_request_context_getter_(new net::TestURLRequestContextGetter( |
| 72 base::ThreadTaskRunnerHandle::Get())) {} | 77 base::ThreadTaskRunnerHandle::Get())), |
| 78 icon_url_(icon_url) {} |
| 73 ~WebApkInstallerRunner() {} | 79 ~WebApkInstallerRunner() {} |
| 74 | 80 |
| 75 void Run() { | 81 void Run() { |
| 76 ShortcutInfo info(GURL::EmptyGURL()); | 82 ShortcutInfo info(GURL::EmptyGURL()); |
| 83 info.icon_url = icon_url_; |
| 77 | 84 |
| 78 // WebApkInstaller owns itself. | 85 // WebApkInstaller owns itself. |
| 79 WebApkInstaller* installer = new TestWebApkInstaller(info, SkBitmap()); | 86 WebApkInstaller* installer = new TestWebApkInstaller(info, SkBitmap()); |
| 80 | 87 |
| 81 installer->SetTimeoutMs(100); | 88 installer->SetTimeoutMs(100); |
| 89 |
| 90 base::RunLoop run_loop; |
| 91 on_completed_callback_ = run_loop.QuitClosure(); |
| 82 installer->InstallAsyncWithURLRequestContextGetter( | 92 installer->InstallAsyncWithURLRequestContextGetter( |
| 83 url_request_context_getter_.get(), | 93 url_request_context_getter_.get(), |
| 84 base::Bind(&WebApkInstallerRunner::OnCompleted, | 94 base::Bind(&WebApkInstallerRunner::OnCompleted, |
| 85 base::Unretained(this))); | 95 base::Unretained(this))); |
| 86 | |
| 87 base::RunLoop run_loop; | |
| 88 on_completed_callback_ = run_loop.QuitClosure(); | |
| 89 run_loop.Run(); | 96 run_loop.Run(); |
| 90 } | 97 } |
| 91 | 98 |
| 92 bool success() { return success_; } | 99 bool success() { return success_; } |
| 93 | 100 |
| 94 private: | 101 private: |
| 95 void OnCompleted(bool success) { | 102 void OnCompleted(bool success) { |
| 96 success_ = success; | 103 success_ = success; |
| 97 on_completed_callback_.Run(); | 104 on_completed_callback_.Run(); |
| 98 } | 105 } |
| 99 | 106 |
| 100 scoped_refptr<net::TestURLRequestContextGetter> | 107 scoped_refptr<net::TestURLRequestContextGetter> |
| 101 url_request_context_getter_; | 108 url_request_context_getter_; |
| 102 | 109 |
| 110 // The Web Manifest's icon URL. |
| 111 const GURL icon_url_; |
| 112 |
| 103 // Called after the installation process has succeeded or failed. | 113 // Called after the installation process has succeeded or failed. |
| 104 base::Closure on_completed_callback_; | 114 base::Closure on_completed_callback_; |
| 105 | 115 |
| 106 // Whether the installation process succeeded. | 116 // Whether the installation process succeeded. |
| 107 bool success_; | 117 bool success_; |
| 108 | 118 |
| 109 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerRunner); | 119 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerRunner); |
| 110 }; | 120 }; |
| 111 | 121 |
| 112 // Builds a webapk::WebApkResponse with |download_url| as the WebAPK download | 122 // Builds a webapk::WebApkResponse with |download_url| as the WebAPK download |
| (...skipping 28 matching lines...) Expand all Loading... |
| 141 void SetUp() override { | 151 void SetUp() override { |
| 142 test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); | 152 test_server_.AddDefaultHandlers(base::FilePath(kTestDataDir)); |
| 143 test_server_.RegisterRequestHandler( | 153 test_server_.RegisterRequestHandler( |
| 144 base::Bind(&WebApkInstallerTest::HandleCreateWebApkRequest, | 154 base::Bind(&WebApkInstallerTest::HandleCreateWebApkRequest, |
| 145 base::Unretained(this))); | 155 base::Unretained(this))); |
| 146 ASSERT_TRUE(test_server_.Start()); | 156 ASSERT_TRUE(test_server_.Start()); |
| 147 | 157 |
| 148 SetDefaults(); | 158 SetDefaults(); |
| 149 } | 159 } |
| 150 | 160 |
| 161 // Sets the Web Manifest's icon URL. |
| 162 void SetIconUrl(const GURL& icon_url) { |
| 163 icon_url_ = icon_url; |
| 164 } |
| 165 |
| 151 // Sets the URL to send the webapk::CreateWebApkRequest to. WebApkInstaller | 166 // Sets the URL to send the webapk::CreateWebApkRequest to. WebApkInstaller |
| 152 // should fail if the URL is not |kServerUrl|. | 167 // should fail if the URL is not |kServerUrl|. |
| 153 void SetWebApkServerUrl(const GURL& server_url) { | 168 void SetWebApkServerUrl(const GURL& server_url) { |
| 154 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 169 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 155 switches::kWebApkServerUrl, server_url.spec()); | 170 switches::kWebApkServerUrl, server_url.spec()); |
| 156 } | 171 } |
| 157 | 172 |
| 158 // Sets the function that should be used to build the response to the | 173 // Sets the function that should be used to build the response to the |
| 159 // WebAPK creation request. | 174 // WebAPK creation request. |
| 160 void SetWebApkResponseBuilder(const WebApkResponseBuilder& builder) { | 175 void SetWebApkResponseBuilder(const WebApkResponseBuilder& builder) { |
| 161 webapk_response_builder_ = builder; | 176 webapk_response_builder_ = builder; |
| 162 } | 177 } |
| 163 | 178 |
| 179 std::unique_ptr<WebApkInstallerRunner> CreateWebApkInstallerRunner() { |
| 180 return std::unique_ptr<WebApkInstallerRunner>( |
| 181 new WebApkInstallerRunner(icon_url_)); |
| 182 } |
| 183 |
| 164 net::test_server::EmbeddedTestServer* test_server() { return &test_server_; } | 184 net::test_server::EmbeddedTestServer* test_server() { return &test_server_; } |
| 165 | 185 |
| 166 private: | 186 private: |
| 167 // Sets default configuration for running WebApkInstaller. | 187 // Sets default configuration for running WebApkInstaller. |
| 168 void SetDefaults() { | 188 void SetDefaults() { |
| 189 GURL icon_url = test_server_.GetURL(kIconUrl); |
| 190 SetIconUrl(icon_url); |
| 169 GURL server_url = test_server_.GetURL(kServerUrl); | 191 GURL server_url = test_server_.GetURL(kServerUrl); |
| 170 SetWebApkServerUrl(server_url); | 192 SetWebApkServerUrl(server_url); |
| 171 GURL download_url = test_server_.GetURL(kDownloadUrl); | 193 GURL download_url = test_server_.GetURL(kDownloadUrl); |
| 172 SetWebApkResponseBuilder( | 194 SetWebApkResponseBuilder( |
| 173 base::Bind(&BuildValidWebApkResponse, download_url)); | 195 base::Bind(&BuildValidWebApkResponse, download_url)); |
| 174 } | 196 } |
| 175 | 197 |
| 176 std::unique_ptr<net::test_server::HttpResponse> HandleCreateWebApkRequest( | 198 std::unique_ptr<net::test_server::HttpResponse> HandleCreateWebApkRequest( |
| 177 const net::test_server::HttpRequest& request) { | 199 const net::test_server::HttpRequest& request) { |
| 178 return (request.relative_url == kServerUrl) | 200 return (request.relative_url == kServerUrl) |
| 179 ? webapk_response_builder_.Run() | 201 ? webapk_response_builder_.Run() |
| 180 : std::unique_ptr<net::test_server::HttpResponse>(); | 202 : std::unique_ptr<net::test_server::HttpResponse>(); |
| 181 } | 203 } |
| 182 | 204 |
| 183 content::TestBrowserThreadBundle thread_bundle_; | 205 content::TestBrowserThreadBundle thread_bundle_; |
| 184 net::EmbeddedTestServer test_server_; | 206 net::EmbeddedTestServer test_server_; |
| 185 | 207 |
| 208 // Web Manifest's icon URL. |
| 209 GURL icon_url_; |
| 210 |
| 186 // Builds response to the WebAPK creation request. | 211 // Builds response to the WebAPK creation request. |
| 187 WebApkResponseBuilder webapk_response_builder_; | 212 WebApkResponseBuilder webapk_response_builder_; |
| 188 | 213 |
| 189 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerTest); | 214 DISALLOW_COPY_AND_ASSIGN(WebApkInstallerTest); |
| 190 }; | 215 }; |
| 191 | 216 |
| 192 // Test installation succeeding. | 217 // Test installation succeeding. |
| 193 TEST_F(WebApkInstallerTest, Success) { | 218 TEST_F(WebApkInstallerTest, Success) { |
| 194 WebApkInstallerRunner runner; | 219 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 195 runner.Run(); | 220 runner->Run(); |
| 196 EXPECT_TRUE(runner.success()); | 221 EXPECT_TRUE(runner->success()); |
| 222 } |
| 223 |
| 224 // Test that installation succeeds when the icon URL is empty. When the icon URL |
| 225 // is empty, the "add to homescreen" logic generates a default app icon. |
| 226 TEST_F(WebApkInstallerTest, SuccessWhenIconUrlEmpty) { |
| 227 SetIconUrl(GURL()); |
| 228 |
| 229 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 230 runner->Run(); |
| 231 EXPECT_TRUE(runner->success()); |
| 232 } |
| 233 |
| 234 // Test that installation fails if fetching the bitmap at the icon URL times |
| 235 // out. In a perfect world the fetch would never time out because the bitmap at |
| 236 // the icon URL should be in the HTTP cache. |
| 237 TEST_F(WebApkInstallerTest, IconUrlDownloadTimesOut) { |
| 238 GURL icon_url = test_server()->GetURL("/slow?1000"); |
| 239 SetIconUrl(icon_url); |
| 240 |
| 241 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 242 runner->Run(); |
| 243 EXPECT_FALSE(runner->success()); |
| 197 } | 244 } |
| 198 | 245 |
| 199 // Test that installation fails if the WebAPK creation request times out. | 246 // Test that installation fails if the WebAPK creation request times out. |
| 200 TEST_F(WebApkInstallerTest, CreateWebApkRequestTimesOut) { | 247 TEST_F(WebApkInstallerTest, CreateWebApkRequestTimesOut) { |
| 201 GURL server_url = test_server()->GetURL("/slow?1000"); | 248 GURL server_url = test_server()->GetURL("/slow?1000"); |
| 202 SetWebApkServerUrl(server_url); | 249 SetWebApkServerUrl(server_url); |
| 203 | 250 |
| 204 WebApkInstallerRunner runner; | 251 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 205 runner.Run(); | 252 runner->Run(); |
| 206 EXPECT_FALSE(runner.success()); | 253 EXPECT_FALSE(runner->success()); |
| 207 } | 254 } |
| 208 | 255 |
| 209 // Test that installation fails if the WebAPK download times out. | 256 // Test that installation fails if the WebAPK download times out. |
| 210 TEST_F(WebApkInstallerTest, WebApkDownloadTimesOut) { | 257 TEST_F(WebApkInstallerTest, WebApkDownloadTimesOut) { |
| 211 GURL download_url = test_server()->GetURL("/slow?1000"); | 258 GURL download_url = test_server()->GetURL("/slow?1000"); |
| 212 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); | 259 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); |
| 213 | 260 |
| 214 WebApkInstallerRunner runner; | 261 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 215 runner.Run(); | 262 runner->Run(); |
| 216 EXPECT_FALSE(runner.success()); | 263 EXPECT_FALSE(runner->success()); |
| 217 } | 264 } |
| 218 | 265 |
| 219 // Test that installation fails if the WebAPK download fails. | 266 // Test that installation fails if the WebAPK download fails. |
| 220 TEST_F(WebApkInstallerTest, WebApkDownloadFails) { | 267 TEST_F(WebApkInstallerTest, WebApkDownloadFails) { |
| 221 GURL download_url = test_server()->GetURL("/nocontent"); | 268 GURL download_url = test_server()->GetURL("/nocontent"); |
| 222 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); | 269 SetWebApkResponseBuilder(base::Bind(&BuildValidWebApkResponse, download_url)); |
| 223 | 270 |
| 224 WebApkInstallerRunner runner; | 271 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 225 runner.Run(); | 272 runner->Run(); |
| 226 EXPECT_FALSE(runner.success()); | 273 EXPECT_FALSE(runner->success()); |
| 227 } | 274 } |
| 228 | 275 |
| 229 namespace { | 276 namespace { |
| 230 | 277 |
| 231 // Returns an HttpResponse which cannot be parsed as a webapk::WebApkResponse. | 278 // Returns an HttpResponse which cannot be parsed as a webapk::WebApkResponse. |
| 232 std::unique_ptr<net::test_server::HttpResponse> | 279 std::unique_ptr<net::test_server::HttpResponse> |
| 233 BuildUnparsableWebApkResponse() { | 280 BuildUnparsableWebApkResponse() { |
| 234 std::unique_ptr<net::test_server::BasicHttpResponse> response( | 281 std::unique_ptr<net::test_server::BasicHttpResponse> response( |
| 235 new net::test_server::BasicHttpResponse()); | 282 new net::test_server::BasicHttpResponse()); |
| 236 response->set_code(net::HTTP_OK); | 283 response->set_code(net::HTTP_OK); |
| 237 response->set_content("😀"); | 284 response->set_content("😀"); |
| 238 return std::move(response); | 285 return std::move(response); |
| 239 } | 286 } |
| 240 | 287 |
| 241 } // anonymous namespace | 288 } // anonymous namespace |
| 242 | 289 |
| 243 // Test that an HTTP response which cannot be parsed as a webapk::WebApkResponse | 290 // Test that an HTTP response which cannot be parsed as a webapk::WebApkResponse |
| 244 // is handled properly. | 291 // is handled properly. |
| 245 TEST_F(WebApkInstallerTest, UnparsableCreateWebApkResponse) { | 292 TEST_F(WebApkInstallerTest, UnparsableCreateWebApkResponse) { |
| 246 SetWebApkResponseBuilder(base::Bind(&BuildUnparsableWebApkResponse)); | 293 SetWebApkResponseBuilder(base::Bind(&BuildUnparsableWebApkResponse)); |
| 247 | 294 |
| 248 WebApkInstallerRunner runner; | 295 std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner(); |
| 249 runner.Run(); | 296 runner->Run(); |
| 250 EXPECT_FALSE(runner.success()); | 297 EXPECT_FALSE(runner->success()); |
| 251 } | 298 } |
| OLD | NEW |