1 // Copyright 2018 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 "chrome/browser/win/conflicts/incompatible_applications_updater.h"
6
7 #include <map>
8 #include <string>
9 #include <utility>
10
11 #include "base/optional.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "base/test/test_reg_util_win.h"
16 #include "base/win/registry.h"
17 #include "base/win/windows_version.h"
18 #include "chrome/browser/win/conflicts/module_info.h"
19 #include "chrome/browser/win/conflicts/module_list_filter.h"
20 #include "chrome/common/chrome_features.h"
21 #include "chrome/test/base/scoped_testing_local_state.h"
22 #include "chrome/test/base/testing_browser_process.h"
23 #include "content/public/common/process_type.h"
24 #include "content/public/test/browser_task_environment.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace {
28
29 // Mocks an empty whitelist and blacklist.
30 class MockModuleListFilter : public ModuleListFilter {
31 public:
32 MockModuleListFilter() = default;
33
IsWhitelisted(base::StringPiece module_basename_hash,base::StringPiece module_code_id_hash) const34 bool IsWhitelisted(base::StringPiece module_basename_hash,
35 base::StringPiece module_code_id_hash) const override {
36 return false;
37 }
38
IsBlacklisted(const ModuleInfoKey & module_key,const ModuleInfoData & module_data) const39 std::unique_ptr<chrome::conflicts::BlacklistAction> IsBlacklisted(
40 const ModuleInfoKey& module_key,
41 const ModuleInfoData& module_data) const override {
42 return nullptr;
43 }
44
45 private:
46 ~MockModuleListFilter() override = default;
47
48 DISALLOW_COPY_AND_ASSIGN(MockModuleListFilter);
49 };
50
51 class MockInstalledApplications : public InstalledApplications {
52 public:
53 MockInstalledApplications() = default;
54 ~MockInstalledApplications() override = default;
55
AddIncompatibleApplication(const base::FilePath & file_path,ApplicationInfo application_info)56 void AddIncompatibleApplication(const base::FilePath& file_path,
57 ApplicationInfo application_info) {
58 applications_.insert({file_path, std::move(application_info)});
59 }
60
GetInstalledApplications(const base::FilePath & file,std::vector<ApplicationInfo> * applications) const61 bool GetInstalledApplications(
62 const base::FilePath& file,
63 std::vector<ApplicationInfo>* applications) const override {
64 auto range = applications_.equal_range(file);
65
66 if (std::distance(range.first, range.second) == 0)
67 return false;
68
69 for (auto it = range.first; it != range.second; ++it)
70 applications->push_back(it->second);
71 return true;
72 }
73
74 private:
75 std::multimap<base::FilePath, ApplicationInfo> applications_;
76
77 DISALLOW_COPY_AND_ASSIGN(MockInstalledApplications);
78 };
79
80 constexpr wchar_t kCertificatePath[] = L"CertificatePath";
81 constexpr wchar_t kCertificateSubject[] = L"CertificateSubject";
82
83 constexpr wchar_t kDllPath1[] = L"c:\\path\\to\\module.dll";
84 constexpr wchar_t kDllPath2[] = L"c:\\some\\shellextension.dll";
85
86 // Returns a new ModuleInfoData marked as loaded into the browser process but
87 // otherwise empty.
CreateLoadedModuleInfoData()88 ModuleInfoData CreateLoadedModuleInfoData() {
89 ModuleInfoData module_data;
90 module_data.module_properties |= ModuleInfoData::kPropertyLoadedModule;
91 module_data.process_types |= ProcessTypeToBit(content::PROCESS_TYPE_BROWSER);
92 module_data.inspection_result = base::make_optional<ModuleInspectionResult>();
93 return module_data;
94 }
95
96 // Returns a new ModuleInfoData marked as loaded into the process with a
97 // CertificateInfo that matches kCertificateSubject.
CreateSignedLoadedModuleInfoData()98 ModuleInfoData CreateSignedLoadedModuleInfoData() {
99 ModuleInfoData module_data = CreateLoadedModuleInfoData();
100
101 module_data.inspection_result->certificate_info.type =
102 CertificateInfo::Type::CERTIFICATE_IN_FILE;
103 module_data.inspection_result->certificate_info.path =
104 base::FilePath(kCertificatePath);
105 module_data.inspection_result->certificate_info.subject = kCertificateSubject;
106
107 return module_data;
108 }
109
110 } // namespace
111
112 class IncompatibleApplicationsUpdaterTest : public testing::Test,
113 public ModuleDatabaseEventSource {
114 protected:
IncompatibleApplicationsUpdaterTest()115 IncompatibleApplicationsUpdaterTest()
116 : dll1_(kDllPath1),
117 dll2_(kDllPath2),
118 scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()),
119 module_list_filter_(base::MakeRefCounted<MockModuleListFilter>()) {
120 exe_certificate_info_.type = CertificateInfo::Type::CERTIFICATE_IN_FILE;
121 exe_certificate_info_.path = base::FilePath(kCertificatePath);
122 exe_certificate_info_.subject = kCertificateSubject;
123 }
124
SetUp()125 void SetUp() override {
126 ASSERT_NO_FATAL_FAILURE(
127 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
128
129 scoped_feature_list_.InitAndEnableFeature(
130 features::kIncompatibleApplicationsWarning);
131 }
132
133 enum class Option {
134 ADD_REGISTRY_ENTRY,
135 NO_REGISTRY_ENTRY,
136 };
AddIncompatibleApplication(const base::FilePath & injected_module_path,const base::string16 & application_name,Option option)137 void AddIncompatibleApplication(const base::FilePath& injected_module_path,
138 const base::string16& application_name,
139 Option option) {
140 static constexpr wchar_t kUninstallRegKeyFormat[] =
141 L"dummy\\uninstall\\%ls";
142
143 const base::string16 registry_key_path =
144 base::StringPrintf(kUninstallRegKeyFormat, application_name.c_str());
145
146 installed_applications_.AddIncompatibleApplication(
147 injected_module_path, {application_name, HKEY_CURRENT_USER,
148 registry_key_path, KEY_WOW64_32KEY});
149
150 if (option == Option::ADD_REGISTRY_ENTRY) {
151 base::win::RegKey reg_key(HKEY_CURRENT_USER, registry_key_path.c_str(),
152 KEY_WOW64_32KEY | KEY_CREATE_SUB_KEY);
153 }
154 }
155
156 std::unique_ptr<IncompatibleApplicationsUpdater>
CreateIncompatibleApplicationsUpdater()157 CreateIncompatibleApplicationsUpdater() {
158 return std::make_unique<IncompatibleApplicationsUpdater>(
159 this, exe_certificate_info_, module_list_filter_,
160 installed_applications_, false);
161 }
162
163 // ModuleDatabaseEventSource:
AddObserver(ModuleDatabaseObserver * observer)164 void AddObserver(ModuleDatabaseObserver* observer) override {}
RemoveObserver(ModuleDatabaseObserver * observer)165 void RemoveObserver(ModuleDatabaseObserver* observer) override {}
166
RunLoopUntilIdle()167 void RunLoopUntilIdle() { base::RunLoop().RunUntilIdle(); }
168
169 const base::FilePath dll1_;
170 const base::FilePath dll2_;
171
172 private:
173 content::BrowserTaskEnvironment task_environment_;
174 ScopedTestingLocalState scoped_testing_local_state_;
175 registry_util::RegistryOverrideManager registry_override_manager_;
176 base::test::ScopedFeatureList scoped_feature_list_;
177
178 CertificateInfo exe_certificate_info_;
179 scoped_refptr<MockModuleListFilter> module_list_filter_;
180 MockInstalledApplications installed_applications_;
181
182 DISALLOW_COPY_AND_ASSIGN(IncompatibleApplicationsUpdaterTest);
183 };
184
185 // Tests that when the Local State cache is empty, no incompatible applications
186 // are returned.
TEST_F(IncompatibleApplicationsUpdaterTest,EmptyCache)187 TEST_F(IncompatibleApplicationsUpdaterTest, EmptyCache) {
188 if (base::win::GetVersion() < base::win::Version::WIN10)
189 return;
190
191 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
192 EXPECT_TRUE(IncompatibleApplicationsUpdater::GetCachedApplications().empty());
193 }
194
195 // IncompatibleApplicationsUpdater doesn't do anything when there is no
196 // registered installed applications.
TEST_F(IncompatibleApplicationsUpdaterTest,NoIncompatibleApplications)197 TEST_F(IncompatibleApplicationsUpdaterTest, NoIncompatibleApplications) {
198 if (base::win::GetVersion() < base::win::Version::WIN10)
199 return;
200
201 auto incompatible_applications_updater =
202 CreateIncompatibleApplicationsUpdater();
203
204 // Simulate some arbitrary module loading into the process.
205 incompatible_applications_updater->OnNewModuleFound(
206 ModuleInfoKey(dll1_, 0, 0), CreateLoadedModuleInfoData());
207 incompatible_applications_updater->OnModuleDatabaseIdle();
208 RunLoopUntilIdle();
209
210 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
211 EXPECT_TRUE(IncompatibleApplicationsUpdater::GetCachedApplications().empty());
212 }
213
TEST_F(IncompatibleApplicationsUpdaterTest,NoTiedApplications)214 TEST_F(IncompatibleApplicationsUpdaterTest, NoTiedApplications) {
215 if (base::win::GetVersion() < base::win::Version::WIN10)
216 return;
217
218 auto incompatible_applications_updater =
219 CreateIncompatibleApplicationsUpdater();
220
221 // Simulate the module loading into the process.
222 ModuleInfoKey module_key(dll1_, 0, 0);
223 incompatible_applications_updater->OnNewModuleFound(
224 module_key, CreateLoadedModuleInfoData());
225 incompatible_applications_updater->OnModuleDatabaseIdle();
226 RunLoopUntilIdle();
227
228 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
229 EXPECT_TRUE(IncompatibleApplicationsUpdater::GetCachedApplications().empty());
230
231 EXPECT_EQ(
232 incompatible_applications_updater->GetModuleWarningDecision(module_key),
233 IncompatibleApplicationsUpdater::ModuleWarningDecision::
234 kNoTiedApplication);
235 }
236
TEST_F(IncompatibleApplicationsUpdaterTest,OneIncompatibility)237 TEST_F(IncompatibleApplicationsUpdaterTest, OneIncompatibility) {
238 if (base::win::GetVersion() < base::win::Version::WIN10)
239 return;
240
241 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
242
243 auto incompatible_applications_updater =
244 CreateIncompatibleApplicationsUpdater();
245
246 // Simulate the module loading into the process.
247 ModuleInfoKey module_key(dll1_, 0, 0);
248 incompatible_applications_updater->OnNewModuleFound(
249 module_key, CreateLoadedModuleInfoData());
250 incompatible_applications_updater->OnModuleDatabaseIdle();
251 RunLoopUntilIdle();
252
253 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
254 auto application_names =
255 IncompatibleApplicationsUpdater::GetCachedApplications();
256 ASSERT_EQ(1u, application_names.size());
257 EXPECT_EQ(L"Foo", application_names[0].info.name);
258 EXPECT_EQ(
259 incompatible_applications_updater->GetModuleWarningDecision(module_key),
260 IncompatibleApplicationsUpdater::ModuleWarningDecision::kIncompatible);
261 }
262
TEST_F(IncompatibleApplicationsUpdaterTest,SameModuleMultipleApplications)263 TEST_F(IncompatibleApplicationsUpdaterTest, SameModuleMultipleApplications) {
264 if (base::win::GetVersion() < base::win::Version::WIN10)
265 return;
266
267 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
268 AddIncompatibleApplication(dll1_, L"Bar", Option::ADD_REGISTRY_ENTRY);
269
270 auto incompatible_applications_updater =
271 CreateIncompatibleApplicationsUpdater();
272
273 // Simulate the module loading into the process.
274 ModuleInfoKey module_key(dll1_, 0, 0);
275 incompatible_applications_updater->OnNewModuleFound(
276 module_key, CreateLoadedModuleInfoData());
277 incompatible_applications_updater->OnModuleDatabaseIdle();
278 RunLoopUntilIdle();
279
280 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
281 auto application_names =
282 IncompatibleApplicationsUpdater::GetCachedApplications();
283 ASSERT_EQ(2u, application_names.size());
284 EXPECT_EQ(
285 incompatible_applications_updater->GetModuleWarningDecision(module_key),
286 IncompatibleApplicationsUpdater::ModuleWarningDecision::kIncompatible);
287 }
288
TEST_F(IncompatibleApplicationsUpdaterTest,MultipleCallsToOnModuleDatabaseIdle)289 TEST_F(IncompatibleApplicationsUpdaterTest,
290 MultipleCallsToOnModuleDatabaseIdle) {
291 if (base::win::GetVersion() < base::win::Version::WIN10)
292 return;
293
294 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
295 AddIncompatibleApplication(dll2_, L"Bar", Option::ADD_REGISTRY_ENTRY);
296
297 auto incompatible_applications_updater =
298 CreateIncompatibleApplicationsUpdater();
299
300 // Simulate the module loading into the process.
301 ModuleInfoKey module_key1(dll1_, 0, 0);
302 incompatible_applications_updater->OnNewModuleFound(
303 module_key1, CreateLoadedModuleInfoData());
304 incompatible_applications_updater->OnModuleDatabaseIdle();
305 RunLoopUntilIdle();
306
307 // Add an additional module.
308 ModuleInfoKey module_key2(dll2_, 0, 0);
309 incompatible_applications_updater->OnNewModuleFound(
310 module_key2, CreateLoadedModuleInfoData());
311 incompatible_applications_updater->OnModuleDatabaseIdle();
312 RunLoopUntilIdle();
313
314 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
315 auto application_names =
316 IncompatibleApplicationsUpdater::GetCachedApplications();
317 ASSERT_EQ(2u, application_names.size());
318 EXPECT_EQ(
319 incompatible_applications_updater->GetModuleWarningDecision(module_key1),
320 IncompatibleApplicationsUpdater::ModuleWarningDecision::kIncompatible);
321 EXPECT_EQ(
322 incompatible_applications_updater->GetModuleWarningDecision(module_key2),
323 IncompatibleApplicationsUpdater::ModuleWarningDecision::kIncompatible);
324 }
325
326 // This is meant to test that cached incompatible applications are persisted
327 // through browser restarts, via the Local State file.
328 //
329 // Since this isn't really doable in a unit test, this test at least check that
330 // the list isn't tied to the lifetime of the IncompatibleApplicationsUpdater
331 // instance. It is assumed that the Local State file works as intended.
TEST_F(IncompatibleApplicationsUpdaterTest,PersistsThroughRestarts)332 TEST_F(IncompatibleApplicationsUpdaterTest, PersistsThroughRestarts) {
333 if (base::win::GetVersion() < base::win::Version::WIN10)
334 return;
335
336 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
337
338 auto incompatible_applications_updater =
339 CreateIncompatibleApplicationsUpdater();
340
341 // Simulate the module loading into the process.
342 incompatible_applications_updater->OnNewModuleFound(
343 ModuleInfoKey(dll1_, 0, 0), CreateLoadedModuleInfoData());
344 incompatible_applications_updater->OnModuleDatabaseIdle();
345 RunLoopUntilIdle();
346
347 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
348
349 // Delete the instance.
350 incompatible_applications_updater = nullptr;
351
352 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
353 }
354
355 // Tests that applications that do not have a registry entry are removed.
TEST_F(IncompatibleApplicationsUpdaterTest,StaleEntriesRemoved)356 TEST_F(IncompatibleApplicationsUpdaterTest, StaleEntriesRemoved) {
357 if (base::win::GetVersion() < base::win::Version::WIN10)
358 return;
359
360 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
361 AddIncompatibleApplication(dll2_, L"Bar", Option::NO_REGISTRY_ENTRY);
362
363 auto incompatible_applications_updater =
364 CreateIncompatibleApplicationsUpdater();
365
366 // Simulate the modules loading into the process.
367 incompatible_applications_updater->OnNewModuleFound(
368 ModuleInfoKey(dll1_, 0, 0), CreateLoadedModuleInfoData());
369 incompatible_applications_updater->OnNewModuleFound(
370 ModuleInfoKey(dll2_, 0, 0), CreateLoadedModuleInfoData());
371 incompatible_applications_updater->OnModuleDatabaseIdle();
372 RunLoopUntilIdle();
373
374 EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
375 auto application_names =
376 IncompatibleApplicationsUpdater::GetCachedApplications();
377 ASSERT_EQ(1u, application_names.size());
378 EXPECT_EQ(L"Foo", application_names[0].info.name);
379 }
380
TEST_F(IncompatibleApplicationsUpdaterTest,IgnoreNotLoadedModules)381 TEST_F(IncompatibleApplicationsUpdaterTest, IgnoreNotLoadedModules) {
382 if (base::win::GetVersion() < base::win::Version::WIN10)
383 return;
384
385 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
386
387 auto incompatible_applications_updater =
388 CreateIncompatibleApplicationsUpdater();
389
390 // Simulate the module loading into the process.
391 ModuleInfoKey module_key(dll1_, 0, 0);
392 ModuleInfoData module_data;
393 module_data.inspection_result = base::make_optional<ModuleInspectionResult>();
394 incompatible_applications_updater->OnNewModuleFound(module_key, module_data);
395 incompatible_applications_updater->OnModuleDatabaseIdle();
396 RunLoopUntilIdle();
397
398 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
399 auto application_names =
400 IncompatibleApplicationsUpdater::GetCachedApplications();
401 ASSERT_EQ(0u, application_names.size());
402 EXPECT_EQ(
403 incompatible_applications_updater->GetModuleWarningDecision(module_key),
404 IncompatibleApplicationsUpdater::ModuleWarningDecision::kNotLoaded);
405 }
406
407 // Tests that modules with a matching certificate subject are whitelisted.
TEST_F(IncompatibleApplicationsUpdaterTest,WhitelistMatchingCertificateSubject)408 TEST_F(IncompatibleApplicationsUpdaterTest,
409 WhitelistMatchingCertificateSubject) {
410 if (base::win::GetVersion() < base::win::Version::WIN10)
411 return;
412
413 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
414
415 auto incompatible_applications_updater =
416 CreateIncompatibleApplicationsUpdater();
417
418 // Simulate the module loading into the process.
419 ModuleInfoKey module_key(dll1_, 0, 0);
420 incompatible_applications_updater->OnNewModuleFound(
421 module_key, CreateSignedLoadedModuleInfoData());
422 incompatible_applications_updater->OnModuleDatabaseIdle();
423 RunLoopUntilIdle();
424
425 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
426 auto application_names =
427 IncompatibleApplicationsUpdater::GetCachedApplications();
428 ASSERT_EQ(0u, application_names.size());
429 EXPECT_EQ(
430 incompatible_applications_updater->GetModuleWarningDecision(module_key),
431 IncompatibleApplicationsUpdater::ModuleWarningDecision::
432 kAllowedSameCertificate);
433 }
434
435 // Registered modules are defined as either a shell extension or an IME.
TEST_F(IncompatibleApplicationsUpdaterTest,IgnoreRegisteredModules)436 TEST_F(IncompatibleApplicationsUpdaterTest, IgnoreRegisteredModules) {
437 if (base::win::GetVersion() < base::win::Version::WIN10)
438 return;
439
440 AddIncompatibleApplication(dll1_, L"Shell Extension",
441 Option::ADD_REGISTRY_ENTRY);
442 AddIncompatibleApplication(dll2_, L"Input Method Editor",
443 Option::ADD_REGISTRY_ENTRY);
444
445 auto incompatible_applications_updater =
446 CreateIncompatibleApplicationsUpdater();
447
448 // Set the respective bit for registered modules.
449 ModuleInfoKey module_key1(dll1_, 0, 0);
450 auto module_data1 = CreateLoadedModuleInfoData();
451 module_data1.module_properties |= ModuleInfoData::kPropertyShellExtension;
452
453 ModuleInfoKey module_key2(dll2_, 0, 0);
454 auto module_data2 = CreateLoadedModuleInfoData();
455 module_data2.module_properties |= ModuleInfoData::kPropertyIme;
456
457 // Simulate the modules loading into the process.
458 incompatible_applications_updater->OnNewModuleFound(module_key1,
459 module_data1);
460 incompatible_applications_updater->OnNewModuleFound(module_key2,
461 module_data2);
462 incompatible_applications_updater->OnModuleDatabaseIdle();
463 RunLoopUntilIdle();
464
465 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
466 auto application_names =
467 IncompatibleApplicationsUpdater::GetCachedApplications();
468 ASSERT_EQ(0u, application_names.size());
469 EXPECT_EQ(
470 incompatible_applications_updater->GetModuleWarningDecision(module_key1),
471 IncompatibleApplicationsUpdater::ModuleWarningDecision::
472 kAllowedShellExtension);
473 EXPECT_EQ(
474 incompatible_applications_updater->GetModuleWarningDecision(module_key2),
475 IncompatibleApplicationsUpdater::ModuleWarningDecision::kAllowedIME);
476 }
477
TEST_F(IncompatibleApplicationsUpdaterTest,IgnoreModulesAddedToTheBlacklist)478 TEST_F(IncompatibleApplicationsUpdaterTest, IgnoreModulesAddedToTheBlacklist) {
479 if (base::win::GetVersion() < base::win::Version::WIN10)
480 return;
481
482 AddIncompatibleApplication(dll1_, L"Blacklisted Application",
483 Option::ADD_REGISTRY_ENTRY);
484
485 auto incompatible_applications_updater =
486 CreateIncompatibleApplicationsUpdater();
487
488 // Set the respective bit for the module.
489 auto module_data = CreateLoadedModuleInfoData();
490 module_data.module_properties |= ModuleInfoData::kPropertyAddedToBlacklist;
491
492 // Simulate the module loading into the process.
493 incompatible_applications_updater->OnNewModuleFound(
494 ModuleInfoKey(dll1_, 0, 0), module_data);
495 incompatible_applications_updater->OnModuleDatabaseIdle();
496 RunLoopUntilIdle();
497
498 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
499 auto application_names =
500 IncompatibleApplicationsUpdater::GetCachedApplications();
501 ASSERT_EQ(0u, application_names.size());
502 }
503
TEST_F(IncompatibleApplicationsUpdaterTest,DisableModuleAnalysis)504 TEST_F(IncompatibleApplicationsUpdaterTest, DisableModuleAnalysis) {
505 if (base::win::GetVersion() < base::win::Version::WIN10)
506 return;
507
508 AddIncompatibleApplication(dll1_, L"Foo", Option::ADD_REGISTRY_ENTRY);
509
510 auto incompatible_applications_updater =
511 CreateIncompatibleApplicationsUpdater();
512
513 incompatible_applications_updater->DisableModuleAnalysis();
514
515 // Simulate the module loading into the process.
516 ModuleInfoKey module_key(dll1_, 0, 0);
517 incompatible_applications_updater->OnNewModuleFound(
518 module_key, CreateLoadedModuleInfoData());
519 incompatible_applications_updater->OnModuleDatabaseIdle();
520 RunLoopUntilIdle();
521
522 // The module does not cause a warning.
523 EXPECT_FALSE(IncompatibleApplicationsUpdater::HasCachedApplications());
524 EXPECT_TRUE(IncompatibleApplicationsUpdater::GetCachedApplications().empty());
525 EXPECT_EQ(
526 incompatible_applications_updater->GetModuleWarningDecision(module_key),
527 IncompatibleApplicationsUpdater::ModuleWarningDecision::kNotAnalyzed);
528 }
529