arc_util_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. // Copyright 2017 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. #include "ash/components/arc/arc_util.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "ash/components/arc/arc_features.h"
  10. #include "ash/components/arc/test/arc_util_test_support.h"
  11. #include "ash/constants/app_types.h"
  12. #include "base/base_switches.h"
  13. #include "base/command_line.h"
  14. #include "base/files/file_util.h"
  15. #include "base/files/scoped_temp_dir.h"
  16. #include "base/memory/ptr_util.h"
  17. #include "base/run_loop.h"
  18. #include "base/test/bind.h"
  19. #include "base/test/scoped_feature_list.h"
  20. #include "chromeos/ash/components/dbus/upstart/fake_upstart_client.h"
  21. #include "components/account_id/account_id.h"
  22. #include "components/exo/shell_surface_util.h"
  23. #include "components/prefs/testing_pref_service.h"
  24. #include "components/user_manager/fake_user_manager.h"
  25. #include "components/user_manager/scoped_user_manager.h"
  26. #include "components/user_manager/user.h"
  27. #include "testing/gtest/include/gtest/gtest.h"
  28. #include "ui/aura/client/aura_constants.h"
  29. #include "ui/aura/test/test_windows.h"
  30. #include "ui/aura/window.h"
  31. #include "ui/display/types/display_constants.h"
  32. namespace arc {
  33. namespace {
  34. // If an instance is created, based on the value passed to the constructor,
  35. // EnableARC feature is enabled/disabled in the scope.
  36. class ScopedArcFeature {
  37. public:
  38. explicit ScopedArcFeature(bool enabled) {
  39. constexpr char kArcFeatureName[] = "EnableARC";
  40. if (enabled) {
  41. feature_list.InitFromCommandLine(kArcFeatureName, std::string());
  42. } else {
  43. feature_list.InitFromCommandLine(std::string(), kArcFeatureName);
  44. }
  45. }
  46. ScopedArcFeature(const ScopedArcFeature&) = delete;
  47. ScopedArcFeature& operator=(const ScopedArcFeature&) = delete;
  48. ~ScopedArcFeature() = default;
  49. private:
  50. base::test::ScopedFeatureList feature_list;
  51. };
  52. class ScopedRtVcpuFeature {
  53. public:
  54. ScopedRtVcpuFeature(bool dual_core_enabled, bool quad_core_enabled) {
  55. std::vector<base::Feature> enabled_features;
  56. std::vector<base::Feature> disabled_features;
  57. if (dual_core_enabled)
  58. enabled_features.push_back(kRtVcpuDualCore);
  59. else
  60. disabled_features.push_back(kRtVcpuDualCore);
  61. if (quad_core_enabled)
  62. enabled_features.push_back(kRtVcpuQuadCore);
  63. else
  64. disabled_features.push_back(kRtVcpuQuadCore);
  65. feature_list.InitWithFeatures(enabled_features, disabled_features);
  66. }
  67. ~ScopedRtVcpuFeature() = default;
  68. ScopedRtVcpuFeature(const ScopedRtVcpuFeature&) = delete;
  69. ScopedRtVcpuFeature& operator=(const ScopedRtVcpuFeature&) = delete;
  70. private:
  71. base::test::ScopedFeatureList feature_list;
  72. };
  73. // Fake user that can be created with a specified type.
  74. class FakeUser : public user_manager::User {
  75. public:
  76. explicit FakeUser(user_manager::UserType user_type)
  77. : User(AccountId::FromUserEmailGaiaId("user@test.com", "1234567890")),
  78. user_type_(user_type) {}
  79. FakeUser(const FakeUser&) = delete;
  80. FakeUser& operator=(const FakeUser&) = delete;
  81. ~FakeUser() override = default;
  82. // user_manager::User:
  83. user_manager::UserType GetType() const override { return user_type_; }
  84. private:
  85. const user_manager::UserType user_type_;
  86. };
  87. class ArcUtilTest : public testing::Test {
  88. public:
  89. ArcUtilTest() { ash::UpstartClient::InitializeFake(); }
  90. ArcUtilTest(const ArcUtilTest&) = delete;
  91. ArcUtilTest& operator=(const ArcUtilTest&) = delete;
  92. ~ArcUtilTest() override = default;
  93. void SetUp() override {
  94. run_loop_ = std::make_unique<base::RunLoop>();
  95. RemoveUpstartStartStopJobFailures();
  96. }
  97. void TearDown() override { run_loop_.reset(); }
  98. protected:
  99. void InjectUpstartStartJobFailure(const std::string& job_name_to_fail) {
  100. auto* upstart_client = ash::FakeUpstartClient::Get();
  101. upstart_client->set_start_job_cb(base::BindLambdaForTesting(
  102. [job_name_to_fail](const std::string& job_name,
  103. const std::vector<std::string>& env) {
  104. // Return success unless |job_name| is |job_name_to_fail|.
  105. return job_name != job_name_to_fail;
  106. }));
  107. }
  108. void InjectUpstartStopJobFailure(const std::string& job_name_to_fail) {
  109. auto* upstart_client = ash::FakeUpstartClient::Get();
  110. upstart_client->set_stop_job_cb(base::BindLambdaForTesting(
  111. [job_name_to_fail](const std::string& job_name,
  112. const std::vector<std::string>& env) {
  113. // Return success unless |job_name| is |job_name_to_fail|.
  114. return job_name != job_name_to_fail;
  115. }));
  116. }
  117. void StartRecordingUpstartOperations() {
  118. auto* upstart_client = ash::FakeUpstartClient::Get();
  119. upstart_client->set_start_job_cb(
  120. base::BindLambdaForTesting([this](const std::string& job_name,
  121. const std::vector<std::string>& env) {
  122. upstart_operations_.emplace_back(job_name, true);
  123. return true;
  124. }));
  125. upstart_client->set_stop_job_cb(
  126. base::BindLambdaForTesting([this](const std::string& job_name,
  127. const std::vector<std::string>& env) {
  128. upstart_operations_.emplace_back(job_name, false);
  129. return true;
  130. }));
  131. }
  132. void RecreateRunLoop() { run_loop_ = std::make_unique<base::RunLoop>(); }
  133. base::RunLoop* run_loop() { return run_loop_.get(); }
  134. const std::vector<std::pair<std::string, bool>>& upstart_operations() const {
  135. return upstart_operations_;
  136. }
  137. private:
  138. void RemoveUpstartStartStopJobFailures() {
  139. auto* upstart_client = ash::FakeUpstartClient::Get();
  140. upstart_client->set_start_job_cb(
  141. ash::FakeUpstartClient::StartStopJobCallback());
  142. upstart_client->set_stop_job_cb(
  143. ash::FakeUpstartClient::StartStopJobCallback());
  144. }
  145. std::unique_ptr<base::RunLoop> run_loop_;
  146. base::test::TaskEnvironment task_environment_;
  147. // List of upstart operations recorded. When it's "start" the boolean is set
  148. // to true.
  149. std::vector<std::pair<std::string, bool>> upstart_operations_;
  150. };
  151. TEST_F(ArcUtilTest, IsArcAvailable_None) {
  152. auto* command_line = base::CommandLine::ForCurrentProcess();
  153. command_line->InitFromArgv({"", "--arc-availability=none"});
  154. EXPECT_FALSE(IsArcAvailable());
  155. // If --arc-availability flag is set to "none", even if Finch experiment is
  156. // turned on, ARC cannot be used.
  157. {
  158. ScopedArcFeature feature(true);
  159. EXPECT_FALSE(IsArcAvailable());
  160. }
  161. }
  162. // Test --arc-available with EnableARC feature combination.
  163. TEST_F(ArcUtilTest, IsArcAvailable_Installed) {
  164. auto* command_line = base::CommandLine::ForCurrentProcess();
  165. // If ARC is not installed, IsArcAvailable() should return false,
  166. // regardless of EnableARC feature.
  167. command_line->InitFromArgv({""});
  168. // Not available, by-default.
  169. EXPECT_FALSE(IsArcAvailable());
  170. EXPECT_FALSE(IsArcKioskAvailable());
  171. {
  172. ScopedArcFeature feature(true);
  173. EXPECT_FALSE(IsArcAvailable());
  174. EXPECT_FALSE(IsArcKioskAvailable());
  175. }
  176. {
  177. ScopedArcFeature feature(false);
  178. EXPECT_FALSE(IsArcAvailable());
  179. EXPECT_FALSE(IsArcKioskAvailable());
  180. }
  181. // If ARC is installed, IsArcAvailable() should return true when EnableARC
  182. // feature is set.
  183. command_line->InitFromArgv({"", "--arc-available"});
  184. // Not available, by-default, too.
  185. EXPECT_FALSE(IsArcAvailable());
  186. // ARC is available in kiosk mode if installed.
  187. EXPECT_TRUE(IsArcKioskAvailable());
  188. {
  189. ScopedArcFeature feature(true);
  190. EXPECT_TRUE(IsArcAvailable());
  191. EXPECT_TRUE(IsArcKioskAvailable());
  192. }
  193. {
  194. ScopedArcFeature feature(false);
  195. EXPECT_FALSE(IsArcAvailable());
  196. EXPECT_TRUE(IsArcKioskAvailable());
  197. }
  198. // If ARC is installed, IsArcAvailable() should return true when EnableARC
  199. // feature is set.
  200. command_line->InitFromArgv({"", "--arc-availability=installed"});
  201. // Not available, by-default, too.
  202. EXPECT_FALSE(IsArcAvailable());
  203. // ARC is available in kiosk mode if installed.
  204. EXPECT_TRUE(IsArcKioskAvailable());
  205. {
  206. ScopedArcFeature feature(true);
  207. EXPECT_TRUE(IsArcAvailable());
  208. EXPECT_TRUE(IsArcKioskAvailable());
  209. }
  210. {
  211. ScopedArcFeature feature(false);
  212. EXPECT_FALSE(IsArcAvailable());
  213. EXPECT_TRUE(IsArcKioskAvailable());
  214. }
  215. }
  216. TEST_F(ArcUtilTest, IsArcAvailable_OfficiallySupported) {
  217. // Regardless of FeatureList, IsArcAvailable() should return true.
  218. auto* command_line = base::CommandLine::ForCurrentProcess();
  219. command_line->InitFromArgv({"", "--enable-arc"});
  220. EXPECT_TRUE(IsArcAvailable());
  221. EXPECT_TRUE(IsArcKioskAvailable());
  222. command_line->InitFromArgv({"", "--arc-availability=officially-supported"});
  223. EXPECT_TRUE(IsArcAvailable());
  224. EXPECT_TRUE(IsArcKioskAvailable());
  225. }
  226. TEST_F(ArcUtilTest, IsArcVmEnabled) {
  227. EXPECT_FALSE(IsArcVmEnabled());
  228. auto* command_line = base::CommandLine::ForCurrentProcess();
  229. command_line->InitFromArgv({"", "--enable-arcvm"});
  230. EXPECT_TRUE(IsArcVmEnabled());
  231. }
  232. TEST_F(ArcUtilTest, IsArcVmRtVcpuEnabled) {
  233. {
  234. ScopedRtVcpuFeature feature(false, false);
  235. EXPECT_FALSE(IsArcVmRtVcpuEnabled(2));
  236. EXPECT_FALSE(IsArcVmRtVcpuEnabled(4));
  237. EXPECT_FALSE(IsArcVmRtVcpuEnabled(8));
  238. }
  239. {
  240. ScopedRtVcpuFeature feature(true, false);
  241. EXPECT_TRUE(IsArcVmRtVcpuEnabled(2));
  242. EXPECT_FALSE(IsArcVmRtVcpuEnabled(4));
  243. EXPECT_FALSE(IsArcVmRtVcpuEnabled(8));
  244. }
  245. {
  246. ScopedRtVcpuFeature feature(false, true);
  247. EXPECT_FALSE(IsArcVmRtVcpuEnabled(2));
  248. EXPECT_TRUE(IsArcVmRtVcpuEnabled(4));
  249. EXPECT_TRUE(IsArcVmRtVcpuEnabled(8));
  250. }
  251. {
  252. ScopedRtVcpuFeature feature(true, true);
  253. EXPECT_TRUE(IsArcVmRtVcpuEnabled(2));
  254. EXPECT_TRUE(IsArcVmRtVcpuEnabled(4));
  255. EXPECT_TRUE(IsArcVmRtVcpuEnabled(8));
  256. }
  257. }
  258. TEST_F(ArcUtilTest, IsArcVmUseHugePages) {
  259. EXPECT_FALSE(IsArcVmUseHugePages());
  260. auto* command_line = base::CommandLine::ForCurrentProcess();
  261. command_line->InitFromArgv({"", "--arcvm-use-hugepages"});
  262. EXPECT_TRUE(IsArcVmUseHugePages());
  263. }
  264. TEST_F(ArcUtilTest, IsArcVmDevConfIgnored) {
  265. EXPECT_FALSE(IsArcVmDevConfIgnored());
  266. auto* command_line = base::CommandLine::ForCurrentProcess();
  267. command_line->InitFromArgv({"", "--ignore-arcvm-dev-conf"});
  268. EXPECT_TRUE(IsArcVmDevConfIgnored());
  269. }
  270. TEST_F(ArcUtilTest, GetArcVmUreadaheadMode) {
  271. constexpr char kArcMemProfile4GbName[] = "4G";
  272. constexpr char kArcMemProfile8GbName[] = "8G";
  273. auto callback_disabled = base::BindRepeating(&GetSystemMemoryInfoForTesting,
  274. kArcMemProfile4GbName);
  275. auto callback_readahead = base::BindRepeating(&GetSystemMemoryInfoForTesting,
  276. kArcMemProfile8GbName);
  277. auto* command_line = base::CommandLine::ForCurrentProcess();
  278. command_line->InitFromArgv({""});
  279. EXPECT_EQ(ArcVmUreadaheadMode::READAHEAD,
  280. GetArcVmUreadaheadMode(callback_readahead));
  281. command_line->InitFromArgv({"", "--arc-disable-ureadahead"});
  282. EXPECT_EQ(ArcVmUreadaheadMode::DISABLED,
  283. GetArcVmUreadaheadMode(callback_readahead));
  284. EXPECT_EQ(ArcVmUreadaheadMode::DISABLED,
  285. GetArcVmUreadaheadMode(callback_disabled));
  286. command_line->InitFromArgv({"", "--arcvm-ureadahead-mode=generate"});
  287. EXPECT_EQ(ArcVmUreadaheadMode::GENERATE,
  288. GetArcVmUreadaheadMode(callback_readahead));
  289. command_line->InitFromArgv({"", "--arcvm-ureadahead-mode=disabled"});
  290. EXPECT_EQ(ArcVmUreadaheadMode::DISABLED,
  291. GetArcVmUreadaheadMode(callback_readahead));
  292. }
  293. TEST_F(ArcUtilTest, UreadaheadDefault) {
  294. EXPECT_FALSE(IsUreadaheadDisabled());
  295. }
  296. TEST_F(ArcUtilTest, UreadaheadDisabled) {
  297. auto* command_line = base::CommandLine::ForCurrentProcess();
  298. command_line->InitFromArgv({"", "--arc-disable-ureadahead"});
  299. EXPECT_TRUE(IsUreadaheadDisabled());
  300. }
  301. // TODO(hidehiko): Add test for IsArcKioskMode().
  302. // It depends on UserManager, but a utility to inject fake instance is
  303. // available only in chrome/. To use it in components/, refactoring is needed.
  304. TEST_F(ArcUtilTest, IsArcOptInVerificationDisabled) {
  305. auto* command_line = base::CommandLine::ForCurrentProcess();
  306. command_line->InitFromArgv({""});
  307. EXPECT_FALSE(IsArcOptInVerificationDisabled());
  308. command_line->InitFromArgv({"", "--disable-arc-opt-in-verification"});
  309. EXPECT_TRUE(IsArcOptInVerificationDisabled());
  310. }
  311. TEST_F(ArcUtilTest, IsArcAllowedForUser) {
  312. user_manager::FakeUserManager* fake_user_manager =
  313. new user_manager::FakeUserManager();
  314. user_manager::ScopedUserManager scoped_user_manager(
  315. base::WrapUnique(fake_user_manager));
  316. TestingPrefServiceSimple local_state;
  317. fake_user_manager->set_local_state(&local_state);
  318. struct {
  319. user_manager::UserType user_type;
  320. bool expected_allowed;
  321. } const kTestCases[] = {
  322. {user_manager::USER_TYPE_REGULAR, true},
  323. {user_manager::USER_TYPE_GUEST, false},
  324. {user_manager::USER_TYPE_PUBLIC_ACCOUNT, true},
  325. {user_manager::USER_TYPE_KIOSK_APP, false},
  326. {user_manager::USER_TYPE_CHILD, true},
  327. {user_manager::USER_TYPE_ARC_KIOSK_APP, true},
  328. {user_manager::USER_TYPE_ACTIVE_DIRECTORY, true},
  329. };
  330. for (const auto& test_case : kTestCases) {
  331. const FakeUser user(test_case.user_type);
  332. EXPECT_EQ(test_case.expected_allowed, IsArcAllowedForUser(&user))
  333. << "User type=" << test_case.user_type;
  334. }
  335. // An ephemeral user is a logged in user but unknown to UserManager when
  336. // ephemeral policy is set.
  337. fake_user_manager->SetEphemeralUsersEnabled(true);
  338. fake_user_manager->UserLoggedIn(
  339. AccountId::FromUserEmailGaiaId("test@test.com", "9876543210"),
  340. "test@test.com-hash", false /* browser_restart */, false /* is_child */);
  341. const user_manager::User* ephemeral_user = fake_user_manager->GetActiveUser();
  342. ASSERT_TRUE(ephemeral_user);
  343. ASSERT_TRUE(fake_user_manager->IsUserCryptohomeDataEphemeral(
  344. ephemeral_user->GetAccountId()));
  345. // Ephemeral user is also allowed for ARC.
  346. EXPECT_TRUE(IsArcAllowedForUser(ephemeral_user));
  347. }
  348. TEST_F(ArcUtilTest, ArcStartModeDefault) {
  349. auto* command_line = base::CommandLine::ForCurrentProcess();
  350. command_line->InitFromArgv({"", "--arc-availability=installed"});
  351. EXPECT_FALSE(ShouldArcAlwaysStart());
  352. EXPECT_FALSE(ShouldArcAlwaysStartWithNoPlayStore());
  353. }
  354. TEST_F(ArcUtilTest, ArcStartModeWithoutPlayStore) {
  355. auto* command_line = base::CommandLine::ForCurrentProcess();
  356. command_line->InitFromArgv(
  357. {"", "--arc-availability=installed",
  358. "--arc-start-mode=always-start-with-no-play-store"});
  359. EXPECT_TRUE(ShouldArcAlwaysStart());
  360. EXPECT_TRUE(ShouldArcAlwaysStartWithNoPlayStore());
  361. }
  362. // Verifies that ARC manual start is activated by switch.
  363. TEST_F(ArcUtilTest, ArcStartModeManually) {
  364. base::CommandLine::ForCurrentProcess()->InitFromArgv(
  365. {"", "--arc-start-mode=manual"});
  366. EXPECT_FALSE(ShouldArcAlwaysStart());
  367. EXPECT_TRUE(ShouldArcStartManually());
  368. }
  369. // Verifies that ARC manual start is disabled by default.
  370. TEST_F(ArcUtilTest, ArcStartModeManuallyDisabledByDefault) {
  371. EXPECT_FALSE(ShouldArcAlwaysStart());
  372. EXPECT_FALSE(ShouldArcStartManually());
  373. }
  374. TEST_F(ArcUtilTest, ScaleFactorToDensity) {
  375. // Test all standard scale factors
  376. EXPECT_EQ(160, GetLcdDensityForDeviceScaleFactor(1.0f));
  377. EXPECT_EQ(160, GetLcdDensityForDeviceScaleFactor(1.25f));
  378. EXPECT_EQ(213, GetLcdDensityForDeviceScaleFactor(1.6f));
  379. EXPECT_EQ(240, GetLcdDensityForDeviceScaleFactor(display::kDsf_1_777));
  380. EXPECT_EQ(240, GetLcdDensityForDeviceScaleFactor(display::kDsf_1_8));
  381. EXPECT_EQ(240, GetLcdDensityForDeviceScaleFactor(2.0f));
  382. EXPECT_EQ(280, GetLcdDensityForDeviceScaleFactor(display::kDsf_2_252));
  383. EXPECT_EQ(280, GetLcdDensityForDeviceScaleFactor(2.4f));
  384. EXPECT_EQ(320, GetLcdDensityForDeviceScaleFactor(display::kDsf_2_666));
  385. // Bad scale factors shouldn't blow up.
  386. EXPECT_EQ(160, GetLcdDensityForDeviceScaleFactor(0.5f));
  387. EXPECT_EQ(160, GetLcdDensityForDeviceScaleFactor(-0.1f));
  388. EXPECT_EQ(180, GetLcdDensityForDeviceScaleFactor(1.5f));
  389. EXPECT_EQ(1200, GetLcdDensityForDeviceScaleFactor(10.f));
  390. auto* command_line = base::CommandLine::ForCurrentProcess();
  391. command_line->InitFromArgv({"", "--arc-scale=280"});
  392. EXPECT_EQ(280, GetLcdDensityForDeviceScaleFactor(1.234f));
  393. command_line->InitFromArgv({"", "--arc-scale=120"});
  394. EXPECT_EQ(120, GetLcdDensityForDeviceScaleFactor(1.234f));
  395. command_line->InitFromArgv({"", "--arc-scale=abc"});
  396. EXPECT_EQ(240, GetLcdDensityForDeviceScaleFactor(2.0));
  397. }
  398. TEST_F(ArcUtilTest, ConfigureUpstartJobs_Success) {
  399. std::deque<JobDesc> jobs{
  400. JobDesc{"Job_2dA", UpstartOperation::JOB_STOP, {}},
  401. JobDesc{"Job_2dB", UpstartOperation::JOB_STOP_AND_START, {}},
  402. JobDesc{"Job_2dC", UpstartOperation::JOB_START, {}},
  403. };
  404. bool result = false;
  405. StartRecordingUpstartOperations();
  406. ConfigureUpstartJobs(jobs,
  407. base::BindLambdaForTesting([&result, this](bool r) {
  408. result = r;
  409. run_loop()->Quit();
  410. }));
  411. run_loop()->Run();
  412. EXPECT_TRUE(result);
  413. auto ops = upstart_operations();
  414. ASSERT_EQ(4u, ops.size());
  415. EXPECT_EQ(ops[0].first, "Job_2dA");
  416. EXPECT_FALSE(ops[0].second);
  417. EXPECT_EQ(ops[1].first, "Job_2dB");
  418. EXPECT_FALSE(ops[1].second);
  419. EXPECT_EQ(ops[2].first, "Job_2dB");
  420. EXPECT_TRUE(ops[2].second);
  421. EXPECT_EQ(ops[3].first, "Job_2dC");
  422. EXPECT_TRUE(ops[3].second);
  423. }
  424. TEST_F(ArcUtilTest, ConfigureUpstartJobs_StopFail) {
  425. std::deque<JobDesc> jobs{
  426. JobDesc{"Job_2dA", UpstartOperation::JOB_STOP, {}},
  427. JobDesc{"Job_2dB", UpstartOperation::JOB_STOP_AND_START, {}},
  428. JobDesc{"Job_2dC", UpstartOperation::JOB_START, {}},
  429. };
  430. // Confirm that failing to stop a job is ignored.
  431. bool result = false;
  432. InjectUpstartStopJobFailure("Job_2dA");
  433. ConfigureUpstartJobs(jobs,
  434. base::BindLambdaForTesting([&result, this](bool r) {
  435. result = r;
  436. run_loop()->Quit();
  437. }));
  438. run_loop()->Run();
  439. EXPECT_TRUE(result);
  440. // Do the same for the second task.
  441. RecreateRunLoop();
  442. result = false;
  443. InjectUpstartStopJobFailure("Job_2dB");
  444. ConfigureUpstartJobs(jobs,
  445. base::BindLambdaForTesting([&result, this](bool r) {
  446. result = r;
  447. run_loop()->Quit();
  448. }));
  449. run_loop()->Run();
  450. EXPECT_TRUE(result);
  451. }
  452. TEST_F(ArcUtilTest, ConfigureUpstartJobs_StartFail) {
  453. std::deque<JobDesc> jobs{
  454. JobDesc{"Job_2dA", UpstartOperation::JOB_STOP, {}},
  455. JobDesc{"Job_2dB", UpstartOperation::JOB_STOP_AND_START, {}},
  456. JobDesc{"Job_2dC", UpstartOperation::JOB_START, {}},
  457. };
  458. // Confirm that failing to start a job is not ignored.
  459. bool result = true;
  460. InjectUpstartStartJobFailure("Job_2dB");
  461. ConfigureUpstartJobs(jobs,
  462. base::BindLambdaForTesting([&result, this](bool r) {
  463. result = r;
  464. run_loop()->Quit();
  465. }));
  466. run_loop()->Run();
  467. EXPECT_FALSE(result);
  468. // Do the same for the third task.
  469. RecreateRunLoop();
  470. result = true;
  471. InjectUpstartStartJobFailure("Job_2dC");
  472. ConfigureUpstartJobs(std::move(jobs),
  473. base::BindLambdaForTesting([&result, this](bool r) {
  474. result = r;
  475. run_loop()->Quit();
  476. }));
  477. run_loop()->Run();
  478. EXPECT_FALSE(result);
  479. }
  480. TEST_F(ArcUtilTest, GetArcWindowTaskId) {
  481. std::unique_ptr<aura::Window> window(
  482. aura::test::CreateTestWindowWithId(100, nullptr));
  483. exo::SetShellApplicationId(window.get(), "org.chromium.arc.100");
  484. {
  485. auto task_id = GetWindowTaskId(window.get());
  486. EXPECT_TRUE(task_id.has_value());
  487. EXPECT_EQ(task_id.value(), 100);
  488. }
  489. {
  490. auto session_id = GetWindowSessionId(window.get());
  491. EXPECT_FALSE(session_id.has_value());
  492. }
  493. {
  494. auto task_or_session_id = GetWindowTaskOrSessionId(window.get());
  495. EXPECT_TRUE(task_or_session_id.has_value());
  496. EXPECT_EQ(task_or_session_id.value(), 100);
  497. }
  498. }
  499. TEST_F(ArcUtilTest, GetArcWindowSessionId) {
  500. std::unique_ptr<aura::Window> window(
  501. aura::test::CreateTestWindowWithId(200, nullptr));
  502. exo::SetShellApplicationId(window.get(), "org.chromium.arc.session.200");
  503. {
  504. auto task_id = GetWindowTaskId(window.get());
  505. EXPECT_FALSE(task_id.has_value());
  506. }
  507. {
  508. auto session_id = GetWindowSessionId(window.get());
  509. EXPECT_TRUE(session_id.has_value());
  510. EXPECT_EQ(session_id.value(), 200);
  511. }
  512. {
  513. auto task_or_session_id = GetWindowTaskOrSessionId(window.get());
  514. EXPECT_TRUE(task_or_session_id.has_value());
  515. EXPECT_EQ(task_or_session_id.value(), 200);
  516. }
  517. }
  518. } // namespace
  519. } // namespace arc