Use enum class for JobLevel

JobLevel can be an enum class (this means we cannot compile code that
supplies wrong values). As the class must be named, the prefix JOB_
becomes redundant, so entries are renamed to kNone etc.

No functional changes. Bad args test no longer necessary as cannot
compile.

Bug: 1108031
Change-Id: I0abef9a7972b3fce658e37c931fd6b95d3129958
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3533430
Reviewed-by: Will Harris <wfh@chromium.org>
Reviewed-by: Xinghui Lu <xinghuilu@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#983648}
NOKEYCHECK=True
GitOrigin-RevId: 185d03d3c3c247cee0805fbd8d929fb3d1345c58
diff --git a/policy/win/sandbox_win.cc b/policy/win/sandbox_win.cc
index 4eb78bd..a68ec0f 100644
--- a/policy/win/sandbox_win.cc
+++ b/policy/win/sandbox_win.cc
@@ -557,7 +557,7 @@
 
 ResultCode SetJobMemoryLimit(const base::CommandLine& cmd_line,
                              TargetPolicy* policy) {
-  DCHECK_NE(policy->GetJobLevel(), JOB_NONE);
+  DCHECK_NE(policy->GetJobLevel(), JobLevel::kNone);
 
 #ifdef _WIN64
   size_t memory_limit = static_cast<size_t>(kDataSizeLimit);
@@ -784,7 +784,7 @@
       static Job* job_object = nullptr;
       if (!job_object) {
         job_object = new Job;
-        DWORD result = job_object->Init(JOB_UNPROTECTED, nullptr, 0, 0);
+        DWORD result = job_object->Init(JobLevel::kUnprotected, nullptr, 0, 0);
         if (result != ERROR_SUCCESS) {
           job_object = nullptr;
           return SBOX_ERROR_CANNOT_INIT_JOB;
@@ -832,7 +832,7 @@
                                    uint32_t ui_exceptions,
                                    TargetPolicy* policy) {
   if (!ShouldSetJobLevel(policy->GetAllowNoSandboxJob()))
-    return policy->SetJobLevel(JOB_NONE, 0);
+    return policy->SetJobLevel(JobLevel::kNone, 0);
 
   ResultCode ret = policy->SetJobLevel(job_level, ui_exceptions);
   if (ret != SBOX_ALL_OK)
@@ -1070,7 +1070,7 @@
   if (result != SBOX_ALL_OK)
     return result;
 
-  result = SetJobLevel(cmd_line, JOB_LOCKDOWN, 0, policy.get());
+  result = SetJobLevel(cmd_line, JobLevel::kLockdown, 0, policy.get());
   if (result != SBOX_ALL_OK)
     return result;
 
@@ -1130,7 +1130,7 @@
     // Set a policy that would normally allow for process creation. This allows
     // the mf cdm process to launch the protected media pipeline process
     // (mfpmp.exe) without process interception.
-    result = policy->SetJobLevel(JOB_INTERACTIVE, 0);
+    result = policy->SetJobLevel(JobLevel::kInteractive, 0);
     if (result != SBOX_ALL_OK)
       return result;
   }
diff --git a/policy/win/sandbox_win_unittest.cc b/policy/win/sandbox_win_unittest.cc
index 2fd138b..cf6f93a 100644
--- a/policy/win/sandbox_win_unittest.cc
+++ b/policy/win/sandbox_win_unittest.cc
@@ -385,7 +385,7 @@
   // detail, but just that GeneratePolicyForSandboxedProcess generated some kind
   // of valid policy.
   EXPECT_EQ(IntegrityLevel::INTEGRITY_LEVEL_LOW, policy->GetIntegrityLevel());
-  EXPECT_EQ(JobLevel::JOB_LOCKDOWN, policy->GetJobLevel());
+  EXPECT_EQ(JobLevel::kLockdown, policy->GetJobLevel());
   EXPECT_EQ(TokenLevel::USER_LOCKDOWN, policy->GetLockdownTokenLevel());
 }
 
diff --git a/win/src/app_container_test.cc b/win/src/app_container_test.cc
index ccfbe91..955a7d3 100644
--- a/win/src/app_container_test.cc
+++ b/win/src/app_container_test.cc
@@ -478,7 +478,7 @@
   if (!features::IsAppContainerSandboxSupported())
     return;
 
-  TestRunner runner(JOB_UNPROTECTED, USER_UNPROTECTED, USER_UNPROTECTED);
+  TestRunner runner(JobLevel::kUnprotected, USER_UNPROTECTED, USER_UNPROTECTED);
 
   EXPECT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetLowBox(kAppContainerSid));
   // Run test once, this ensures the app container directory exists, we
@@ -492,7 +492,8 @@
       ::CreateEvent(nullptr, false, false, event_name.c_str()));
   ASSERT_TRUE(event.IsValid());
 
-  TestRunner runner2(JOB_UNPROTECTED, USER_UNPROTECTED, USER_UNPROTECTED);
+  TestRunner runner2(JobLevel::kUnprotected, USER_UNPROTECTED,
+                     USER_UNPROTECTED);
   EXPECT_EQ(SBOX_TEST_DENIED, runner2.RunTest(L"AppContainerEvent_Open test"));
 }
 
@@ -524,7 +525,7 @@
     return;
 
   policy_->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
@@ -540,7 +541,7 @@
     return;
 
   policy_->SetTokenLevel(USER_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
@@ -559,7 +560,7 @@
   container_->AddCapability(
       base::win::WellKnownCapability::kInternetClientServer);
   policy_->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
@@ -578,7 +579,7 @@
   container_->AddCapability(
       base::win::WellKnownCapability::kInternetClientServer);
   policy_->SetTokenLevel(USER_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
@@ -601,7 +602,7 @@
   container_->AddImpersonationCapability(
       base::win::WellKnownCapability::kPicturesLibrary);
   policy_->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
@@ -620,7 +621,7 @@
 
   container_->SetEnableLowPrivilegeAppContainer(true);
   policy_->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
-  policy_->SetJobLevel(JOB_NONE, 0);
+  policy_->SetJobLevel(JobLevel::kNone, 0);
 
   CreateProcess();
   auto security_capabilities = container_->GetSecurityCapabilities();
diff --git a/win/src/broker_services.cc b/win/src/broker_services.cc
index 0f5c975..9a05177 100644
--- a/win/src/broker_services.cc
+++ b/win/src/broker_services.cc
@@ -502,7 +502,7 @@
   startup_info->SetMitigations(policy_base->GetProcessMitigations());
 
   if (base::win::GetVersion() >= base::win::Version::WIN10_TH2 &&
-      policy_base->GetJobLevel() <= JOB_LIMITED_USER) {
+      policy_base->GetJobLevel() <= JobLevel::kLimitedUser) {
     startup_info->SetRestrictChildProcessCreation(true);
   }
 
@@ -549,7 +549,8 @@
     return result;
   }
 
-  if (policy_base->HasJob() && policy_base->GetJobLevel() <= JOB_LIMITED_USER) {
+  if (policy_base->HasJob() &&
+      policy_base->GetJobLevel() <= JobLevel::kLimitedUser) {
     // Restrict the job from containing any processes. Job restrictions
     // are only applied at process creation, so the target process is
     // unaffected.
diff --git a/win/src/integrity_level_test.cc b/win/src/integrity_level_test.cc
index b698cc1..ed56e9b 100644
--- a/win/src/integrity_level_test.cc
+++ b/win/src/integrity_level_test.cc
@@ -43,8 +43,8 @@
 }
 
 std::unique_ptr<TestRunner> LowILRealRunner() {
-  auto runner = std::make_unique<TestRunner>(JOB_LOCKDOWN, USER_INTERACTIVE,
-                                             USER_INTERACTIVE);
+  auto runner = std::make_unique<TestRunner>(
+      JobLevel::kLockdown, USER_INTERACTIVE, USER_INTERACTIVE);
   runner->SetTimeout(INFINITE);
   runner->GetPolicy()->SetAlternateDesktop(true);
   runner->GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
@@ -61,8 +61,8 @@
 }
 
 std::unique_ptr<TestRunner> LowILDelayedRunner() {
-  auto runner = std::make_unique<TestRunner>(JOB_LOCKDOWN, USER_INTERACTIVE,
-                                             USER_INTERACTIVE);
+  auto runner = std::make_unique<TestRunner>(
+      JobLevel::kLockdown, USER_INTERACTIVE, USER_INTERACTIVE);
   runner->SetTimeout(INFINITE);
   runner->GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   return runner;
@@ -78,7 +78,7 @@
 }
 
 TEST(IntegrityLevelTest, TestNoILChange) {
-  TestRunner runner(JOB_LOCKDOWN, USER_INTERACTIVE, USER_INTERACTIVE);
+  TestRunner runner(JobLevel::kLockdown, USER_INTERACTIVE, USER_INTERACTIVE);
 
   runner.SetTimeout(INFINITE);
 
@@ -86,7 +86,8 @@
 }
 
 TEST(IntegrityLevelTest, TestUntrustedIL) {
-  TestRunner runner(JOB_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner(JobLevel::kLockdown, USER_RESTRICTED_SAME_ACCESS,
+                    USER_LOCKDOWN);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
   runner.GetPolicy()->SetLockdownDefaultDacl();
@@ -98,7 +99,8 @@
 }
 
 TEST(IntegrityLevelTest, TestLowIL) {
-  TestRunner runner(JOB_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner(JobLevel::kLockdown, USER_RESTRICTED_SAME_ACCESS,
+                    USER_LOCKDOWN);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetLockdownDefaultDacl();
diff --git a/win/src/job.cc b/win/src/job.cc
index f9097b6..9f246cb 100644
--- a/win/src/job.cc
+++ b/win/src/job.cc
@@ -36,7 +36,7 @@
   // Set the settings for the different security levels. Note: The higher levels
   // inherit from the lower levels.
   switch (security_level) {
-    case JOB_LOCKDOWN: {
+    case JobLevel::kLockdown: {
       jeli.BasicLimitInformation.LimitFlags |=
           JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
@@ -45,19 +45,19 @@
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS;
       [[fallthrough]];
     }
-    case JOB_LIMITED_USER: {
+    case JobLevel::kLimitedUser: {
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS;
       jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
       jeli.BasicLimitInformation.ActiveProcessLimit = 1;
       [[fallthrough]];
     }
-    case JOB_INTERACTIVE: {
+    case JobLevel::kInteractive: {
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS;
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP;
       jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
       [[fallthrough]];
     }
-    case JOB_UNPROTECTED: {
+    case JobLevel::kUnprotected: {
       if (memory_limit) {
         jeli.BasicLimitInformation.LimitFlags |=
             JOB_OBJECT_LIMIT_PROCESS_MEMORY;
@@ -68,7 +68,9 @@
           JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
       break;
     }
-    default: { return ERROR_BAD_ARGUMENTS; }
+    case JobLevel::kNone: {
+      return ERROR_BAD_ARGUMENTS;
+    }
   }
 
   if (!::SetInformationJobObject(job_handle_.Get(),
diff --git a/win/src/job.h b/win/src/job.h
index 1bef847..d47a4e4 100644
--- a/win/src/job.h
+++ b/win/src/job.h
@@ -8,14 +8,14 @@
 #include <stddef.h>
 
 #include "base/win/scoped_handle.h"
-#include "sandbox/win/src/restricted_token_utils.h"
 
 namespace sandbox {
+enum class JobLevel;
 
 // Handles the creation of job objects based on a security profile.
 // Sample usage:
 //   Job job;
-//   job.Init(JOB_LOCKDOWN, nullptr);  //no job name
+//   job.Init(JobLevel::kLockdown, nullptr);  //no job name
 //   job.AssignProcessToJob(process_handle);
 class Job {
  public:
diff --git a/win/src/job_unittest.cc b/win/src/job_unittest.cc
index 2af3f27..efb81a8 100644
--- a/win/src/job_unittest.cc
+++ b/win/src/job_unittest.cc
@@ -7,6 +7,7 @@
 #include "sandbox/win/src/job.h"
 
 #include "base/win/scoped_process_information.h"
+#include "sandbox/win/src/security_level.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sandbox {
@@ -18,7 +19,7 @@
     // Create the job.
     Job job;
     ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-              job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0, 0));
+              job.Init(JobLevel::kLockdown, L"my_test_job_name", 0, 0));
 
     // check if the job exists.
     HANDLE job_handle =
@@ -43,7 +44,7 @@
     // Create the job.
     Job job;
     ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-              job.Init(JOB_LOCKDOWN, L"my_test_job_name",
+              job.Init(JobLevel::kLockdown, L"my_test_job_name",
                        JOB_OBJECT_UILIMIT_READCLIPBOARD, 0));
 
     job_handle = job.GetHandle();
@@ -62,7 +63,7 @@
     // Create the job.
     Job job;
     ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-              job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0, 0));
+              job.Init(JobLevel::kLockdown, L"my_test_job_name", 0, 0));
 
     job_handle = job.GetHandle();
     ASSERT_TRUE(job_handle != INVALID_HANDLE_VALUE);
@@ -82,9 +83,9 @@
   // Create the job.
   Job job;
   ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0, 0));
+            job.Init(JobLevel::kLockdown, L"my_test_job_name", 0, 0));
   ASSERT_EQ(static_cast<DWORD>(ERROR_ALREADY_INITIALIZED),
-            job.Init(JOB_LOCKDOWN, L"test", 0, 0));
+            job.Init(JobLevel::kLockdown, L"test", 0, 0));
 }
 
 // Tests the error case when we use a method and the object is not yet
@@ -101,29 +102,27 @@
 TEST(JobTest, SecurityLevel) {
   Job job_lockdown;
   ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job_lockdown.Init(JOB_LOCKDOWN, L"job_lockdown", 0, 0));
+            job_lockdown.Init(JobLevel::kLockdown, L"job_lockdown", 0, 0));
 
   Job job_limited_user;
-  ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job_limited_user.Init(JOB_LIMITED_USER, L"job_limited_user", 0, 0));
+  ASSERT_EQ(
+      static_cast<DWORD>(ERROR_SUCCESS),
+      job_limited_user.Init(JobLevel::kLimitedUser, L"job_limited_user", 0, 0));
 
   Job job_interactive;
-  ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job_interactive.Init(JOB_INTERACTIVE, L"job_interactive", 0, 0));
+  ASSERT_EQ(
+      static_cast<DWORD>(ERROR_SUCCESS),
+      job_interactive.Init(JobLevel::kInteractive, L"job_interactive", 0, 0));
 
   Job job_unprotected;
-  ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job_unprotected.Init(JOB_UNPROTECTED, L"job_unprotected", 0, 0));
+  ASSERT_EQ(
+      static_cast<DWORD>(ERROR_SUCCESS),
+      job_unprotected.Init(JobLevel::kUnprotected, L"job_unprotected", 0, 0));
 
-  // JOB_NONE means we run without a job object so Init should fail.
+  // JobLevel::kNone means we run without a job object so Init should fail.
   Job job_none;
   ASSERT_EQ(static_cast<DWORD>(ERROR_BAD_ARGUMENTS),
-            job_none.Init(JOB_NONE, L"job_none", 0, 0));
-
-  Job job_bad_args;
-  ASSERT_EQ(static_cast<DWORD>(ERROR_BAD_ARGUMENTS),
-            job_bad_args.Init(static_cast<JobLevel>(JOB_NONE + 1),
-                              L"job_bad_args", 0, 0));
+            job_none.Init(JobLevel::kNone, L"job_none", 0, 0));
 }
 
 // Tests the method "AssignProcessToJob".
@@ -131,7 +130,7 @@
   // Create the job.
   Job job;
   ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
-            job.Init(JOB_UNPROTECTED, L"job_test_process", 0, 0));
+            job.Init(JobLevel::kUnprotected, L"job_test_process", 0, 0));
 
   wchar_t notepad[] = L"notepad";
   STARTUPINFO si = {sizeof(si)};
diff --git a/win/src/policy_target_test.cc b/win/src/policy_target_test.cc
index 1712142..5f625ae 100644
--- a/win/src/policy_target_test.cc
+++ b/win/src/policy_target_test.cc
@@ -226,7 +226,8 @@
 }
 
 TEST(PolicyTargetTest, PolicyBaseNoJobLifetime) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                    USER_LOCKDOWN);
   runner.SetReleasePolicyInRun(true);
   // TargetPolicy and its SharedMemIPCServer should continue to exist until
   // the child process dies.
diff --git a/win/src/process_mitigations_unittest.cc b/win/src/process_mitigations_unittest.cc
index 551b07d..63bbaa2 100644
--- a/win/src/process_mitigations_unittest.cc
+++ b/win/src/process_mitigations_unittest.cc
@@ -1023,8 +1023,8 @@
 
 //------------------------------------------------------------------------------
 // Disable child process creation.
-// - JobLevel <= JOB_LIMITED_USER (on < WIN10_TH2).
-// - JobLevel <= JOB_LIMITED_USER which also triggers setting
+// - JobLevel <= JobLevel::kLimitedUser (on < WIN10_TH2).
+// - JobLevel <= JobLevel::kLimitedUser which also triggers setting
 //   PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY to
 //   PROCESS_CREATION_CHILD_PROCESS_RESTRICTED in
 //   BrokerServicesBase::SpawnTarget (on >= WIN10_TH2).
@@ -1038,7 +1038,7 @@
   sandbox::TargetPolicy* policy = runner.GetPolicy();
 
   // Set a policy that would normally allow for process creation.
-  policy->SetJobLevel(JOB_INTERACTIVE, 0);
+  policy->SetJobLevel(JobLevel::kInteractive, 0);
   policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
   runner.SetDisableCsrss(false);
 
@@ -1060,9 +1060,9 @@
   TestRunner runner;
   sandbox::TargetPolicy* policy = runner.GetPolicy();
 
-  // Now set the job level to be <= JOB_LIMITED_USER
+  // Now set the job level to be <= JobLevel::kLimitedUser
   // and ensure we can no longer create a child process.
-  policy->SetJobLevel(JOB_LIMITED_USER, 0);
+  policy->SetJobLevel(JobLevel::kLimitedUser, 0);
   policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
   runner.SetDisableCsrss(false);
 
@@ -1088,7 +1088,7 @@
   sandbox::TargetPolicy* policy = runner.GetPolicy();
 
   // Set a policy that would normally allow for process creation.
-  policy->SetJobLevel(JOB_INTERACTIVE, 0);
+  policy->SetJobLevel(JobLevel::kInteractive, 0);
   policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
   runner.SetDisableCsrss(false);
 
diff --git a/win/src/process_policy_test.cc b/win/src/process_policy_test.cc
index f4d7d22..a610afb 100644
--- a/win/src/process_policy_test.cc
+++ b/win/src/process_policy_test.cc
@@ -117,7 +117,7 @@
 // This tests that the CreateThread works with CSRSS not locked down.
 // In other words, that the interception passes through OK.
 TEST(ProcessPolicyTest, TestCreateThreadWithCsrss) {
-  TestRunner runner(JOB_NONE, USER_INTERACTIVE, USER_INTERACTIVE);
+  TestRunner runner(JobLevel::kNone, USER_INTERACTIVE, USER_INTERACTIVE);
   runner.SetDisableCsrss(false);
   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_CreateThread"));
 }
@@ -125,7 +125,7 @@
 // This tests that the CreateThread works with CSRSS locked down.
 // In other words, that the interception correctly works.
 TEST(ProcessPolicyTest, TestCreateThreadWithoutCsrss) {
-  TestRunner runner(JOB_NONE, USER_INTERACTIVE, USER_INTERACTIVE);
+  TestRunner runner(JobLevel::kNone, USER_INTERACTIVE, USER_INTERACTIVE);
   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_CreateThread"));
 }
 
diff --git a/win/src/restricted_token_test.cc b/win/src/restricted_token_test.cc
index 44d91fd..a2b0a10 100644
--- a/win/src/restricted_token_test.cc
+++ b/win/src/restricted_token_test.cc
@@ -24,7 +24,8 @@
 int RunOpenProcessTest(bool unsandboxed,
                        bool lockdown_dacl,
                        DWORD access_mask) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                    USER_LOCKDOWN);
   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   if (lockdown_dacl)
@@ -33,7 +34,8 @@
   // This spins up a renderer level process, we don't care about the result.
   runner.RunTest(L"IntegrationTestsTest_args 1");
 
-  TestRunner runner2(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
+  TestRunner runner2(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                     USER_LIMITED);
   runner2.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner2.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner2.SetUnsandboxed(unsandboxed);
@@ -46,7 +48,7 @@
 int RunRestrictedOpenProcessTest(bool unsandboxed,
                                  bool lockdown_dacl,
                                  DWORD access_mask) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   if (lockdown_dacl) {
@@ -57,7 +59,8 @@
   // This spins up a GPU level process, we don't care about the result.
   runner.RunTest(L"IntegrationTestsTest_args 1");
 
-  TestRunner runner2(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
+  TestRunner runner2(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                     USER_LIMITED);
   runner2.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner2.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner2.SetUnsandboxed(unsandboxed);
@@ -68,7 +71,7 @@
 }
 
 int RunRestrictedSelfOpenProcessTest(bool add_random_sid, DWORD access_mask) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
   runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
   runner.GetPolicy()->SetLockdownDefaultDacl();
@@ -154,7 +157,7 @@
 }
 
 TEST(RestrictedTokenTest, CheckNonAdminRestricted) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS,
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
                     USER_RESTRICTED_NON_ADMIN);
   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
             runner.RunTest(L"RestrictedTokenTest_IsRestricted"));
diff --git a/win/src/sandbox_policy.h b/win/src/sandbox_policy.h
index dd3c1b1..a56ffc4 100644
--- a/win/src/sandbox_policy.h
+++ b/win/src/sandbox_policy.h
@@ -118,7 +118,7 @@
   // length in:
   //   http://msdn2.microsoft.com/en-us/library/ms684152.aspx
   //
-  // Note: the recommended level is JOB_LOCKDOWN.
+  // Note: the recommended level is JobLevel::kLockdown.
   virtual ResultCode SetJobLevel(JobLevel job_level,
                                  uint32_t ui_exceptions) = 0;
 
diff --git a/win/src/sandbox_policy_base.cc b/win/src/sandbox_policy_base.cc
index 77c0d1a..abdf0ea 100644
--- a/win/src/sandbox_policy_base.cc
+++ b/win/src/sandbox_policy_base.cc
@@ -92,7 +92,7 @@
     : ref_count(1),
       lockdown_level_(USER_LOCKDOWN),
       initial_level_(USER_LOCKDOWN),
-      job_level_(JOB_LOCKDOWN),
+      job_level_(JobLevel::kLockdown),
       ui_exceptions_(0),
       memory_limit_(0),
       use_alternate_desktop_(false),
@@ -153,7 +153,7 @@
   // Cannot set this after the job has been initialized.
   if (job_.IsValid())
     return SBOX_ERROR_BAD_PARAMS;
-  if (memory_limit_ && job_level == JOB_NONE) {
+  if (memory_limit_ && job_level == JobLevel::kNone) {
     return SBOX_ERROR_BAD_PARAMS;
   }
   job_level_ = job_level;
@@ -398,7 +398,7 @@
   if (job_.IsValid())
     return SBOX_ERROR_BAD_PARAMS;
 
-  if (job_level_ == JOB_NONE)
+  if (job_level_ == JobLevel::kNone)
     return SBOX_ALL_OK;
 
   // Create the Windows job object.
@@ -421,7 +421,7 @@
   if (!job_.IsValid())
     return SBOX_ERROR_BAD_PARAMS;
 
-  if (job_level_ >= JOB_INTERACTIVE)
+  if (job_level_ >= JobLevel::kInteractive)
     return SBOX_ALL_OK;
 
   if (ERROR_SUCCESS != job_.SetActiveProcessLimit(0))
diff --git a/win/src/sandbox_policy_diagnostic.cc b/win/src/sandbox_policy_diagnostic.cc
index 8356419..67181aa 100644
--- a/win/src/sandbox_policy_diagnostic.cc
+++ b/win/src/sandbox_policy_diagnostic.cc
@@ -75,15 +75,15 @@
 
 std::string GetJobLevelInEnglish(JobLevel job) {
   switch (job) {
-    case JOB_LOCKDOWN:
+    case JobLevel::kLockdown:
       return "Lockdown";
-    case JOB_LIMITED_USER:
+    case JobLevel::kLimitedUser:
       return "Limited User";
-    case JOB_INTERACTIVE:
+    case JobLevel::kInteractive:
       return "Interactive";
-    case JOB_UNPROTECTED:
+    case JobLevel::kUnprotected:
       return "Unprotected";
-    case JOB_NONE:
+    case JobLevel::kNone:
       return "None";
   }
 }
diff --git a/win/src/sandbox_policy_diagnostic.h b/win/src/sandbox_policy_diagnostic.h
index 9cb7467..6bbe5e0 100644
--- a/win/src/sandbox_policy_diagnostic.h
+++ b/win/src/sandbox_policy_diagnostic.h
@@ -43,7 +43,7 @@
   std::unique_ptr<std::string> json_string_;
   uint32_t process_id_;
   TokenLevel lockdown_level_ = USER_LAST;
-  JobLevel job_level_ = JOB_NONE;
+  JobLevel job_level_ = JobLevel::kNone;
   IntegrityLevel desired_integrity_level_ = INTEGRITY_LEVEL_LAST;
   MitigationFlags desired_mitigations_ = 0;
   absl::optional<base::win::Sid> app_container_sid_;
diff --git a/win/src/security_level.h b/win/src/security_level.h
index 4110bc6..4cf0c0e 100644
--- a/win/src/security_level.h
+++ b/win/src/security_level.h
@@ -99,22 +99,22 @@
 //  JobLevel        |General                            |Quota               |
 //                  |restrictions                       |restrictions        |
 // -----------------|---------------------------------- |--------------------|
-// JOB_NONE         | No job is assigned to the         | None               |
+// kNone            | No job is assigned to the         | None               |
 //                  | sandboxed process.                |                    |
 // -----------------|---------------------------------- |--------------------|
-// JOB_UNPROTECTED  | None                              | *Kill on Job close.|
+// kUnprotected     | None                              | *Kill on Job close.|
 // -----------------|---------------------------------- |--------------------|
-// JOB_INTERACTIVE  | *Forbid system-wide changes using |                    |
+// kInteractive     | *Forbid system-wide changes using |                    |
 //                  |  SystemParametersInfo().          | *Kill on Job close.|
 //                  | *Forbid the creation/switch of    |                    |
 //                  |  Desktops.                        |                    |
 //                  | *Forbids calls to ExitWindows().  |                    |
 // -----------------|---------------------------------- |--------------------|
-// JOB_LIMITED_USER | Same as INTERACTIVE_USER plus:    | *One active process|
+// kLimitedUser     | Same as kInteractive plus:        | *One active process|
 //                  | *Forbid changes to the display    |  limit.            |
 //                  |  settings.                        | *Kill on Job close.|
 // -----------------|---------------------------------- |--------------------|
-// JOB_LOCKDOWN     | Same as LIMITED_USER plus:        | *One active process|
+// kLockdown        | Same as kLimitedUser plus:        | *One active process|
 //                  | * No read/write to the clipboard. |  limit.            |
 //                  | * No access to User Handles that  | *Kill on Job close.|
 //                  |   belong to other processes.      | *Kill on unhandled |
@@ -127,12 +127,12 @@
 // In the context of the above table, 'user handles' refers to the handles of
 // windows, bitmaps, menus, etc. Files, treads and registry handles are kernel
 // handles and are not affected by the job level settings.
-enum JobLevel {
-  JOB_LOCKDOWN = 0,
-  JOB_LIMITED_USER,
-  JOB_INTERACTIVE,
-  JOB_UNPROTECTED,
-  JOB_NONE
+enum class JobLevel {
+  kLockdown = 0,
+  kLimitedUser,
+  kInteractive,
+  kUnprotected,
+  kNone
 };
 
 // These flags correspond to various process-level mitigations (eg. ASLR and
diff --git a/win/tests/common/controller.cc b/win/tests/common/controller.cc
index ffab034..6ffcced 100644
--- a/win/tests/common/controller.cc
+++ b/win/tests/common/controller.cc
@@ -126,7 +126,9 @@
 }
 
 TestRunner::TestRunner()
-    : TestRunner(JOB_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN) {}
+    : TestRunner(JobLevel::kLockdown,
+                 USER_RESTRICTED_SAME_ACCESS,
+                 USER_LOCKDOWN) {}
 
 TargetPolicy* TestRunner::GetPolicy() {
   return policy_.get();
diff --git a/win/tests/integration_tests/integration_tests_test.cc b/win/tests/integration_tests/integration_tests_test.cc
index a040d1e..9f757de 100644
--- a/win/tests/integration_tests/integration_tests_test.cc
+++ b/win/tests/integration_tests/integration_tests_test.cc
@@ -142,8 +142,8 @@
 
 // Creates a job and tries to run a process inside it. The function can be
 // called with up to two parameters. The first one if set to "none" means that
-// the child process should be run with the JOB_NONE JobLevel else it is run
-// with JOB_LOCKDOWN level. The second if present specifies that the
+// the child process should be run with the JobLevel::kNone JobLevel else it is
+// run with JobLevel::kLockdown level. The second if present specifies that the
 // JOB_OBJECT_LIMIT_BREAKAWAY_OK flag should be set on the job object created
 // in this function. The return value is either SBOX_TEST_SUCCEEDED if the test
 // has passed or a value between 0 and 4 indicating which part of the test has
@@ -174,9 +174,9 @@
   if (!::AssignProcessToJobObject(job, ::GetCurrentProcess()))
     return 3;
 
-  JobLevel job_level = JOB_LOCKDOWN;
+  JobLevel job_level = JobLevel::kLockdown;
   if (argc > 0 && wcscmp(argv[0], L"none") == 0)
-    job_level = JOB_NONE;
+    job_level = JobLevel::kNone;
 
   TestRunner runner(job_level, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
   runner.SetTimeout(TestTimeouts::action_timeout());
@@ -242,7 +242,8 @@
 }
 
 TEST(IntegrationTestsTest, NoWaitForStuckChildNoJob) {
-  TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                    USER_LOCKDOWN);
   runner.SetTimeout(TestTimeouts::action_timeout());
   runner.SetAsynchronous(true);
   runner.SetKillOnDestruction(false);
@@ -263,7 +264,8 @@
   runner.SetTimeout(TestTimeouts::action_timeout());
   runner.SetAsynchronous(true);
   runner.SetKillOnDestruction(false);
-  TestRunner runner2(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner2(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                     USER_LOCKDOWN);
   runner2.SetTimeout(TestTimeouts::action_timeout());
   runner2.SetAsynchronous(true);
   runner2.SetKillOnDestruction(false);
@@ -289,7 +291,8 @@
   runner.SetTimeout(TestTimeouts::action_timeout());
   runner.SetAsynchronous(true);
   runner.SetKillOnDestruction(false);
-  TestRunner runner2(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+  TestRunner runner2(JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS,
+                     USER_LOCKDOWN);
   runner2.SetTimeout(TestTimeouts::action_timeout());
   runner2.SetAsynchronous(true);
   runner2.SetKillOnDestruction(false);
@@ -312,7 +315,7 @@
 
 std::unique_ptr<TestRunner> StuckChildrenRunner() {
   auto runner = std::make_unique<TestRunner>(
-      JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
+      JobLevel::kNone, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
   runner->SetTimeout(TestTimeouts::action_timeout());
   runner->SetAsynchronous(true);
   runner->SetKillOnDestruction(false);