// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "login_manager/chrome_setup.h"

#include <sys/stat.h>
#include <unistd.h>

#include <array>
#include <set>
#include <utility>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/hash/sha1.h>
#include <base/json/json_writer.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <base/values.h>
#include <brillo/userdb_utils.h>
#include <chromeos-config/libcros_config/cros_config_interface.h>
#include <chromeos/ui/chromium_command_builder.h>
#include <chromeos/ui/util.h>
#include <policy/device_policy.h>
#include <policy/libpolicy.h>

// IMPORTANT: If you want to check for the presence of a new USE flag within
// this file via UseFlagIsSet(), you need to add it to the IUSE list in the
// libchromeos-use-flags package's ebuild file. See docs/flags.md for more
// information about this file.

using chromeos::ui::ChromiumCommandBuilder;
using chromeos::ui::util::EnsureDirectoryExists;

namespace login_manager {

constexpr char kUiPath[] = "/ui";
constexpr char kSerializedAshFlagsProperty[] = "serialized-ash-flags";

const char kWallpaperProperty[] = "wallpaper";

const char kRegulatoryLabelProperty[] = "regulatory-label";

const char kPowerButtonPositionPath[] = "/ui/power-button";
const char kPowerButtonEdgeField[] = "edge";
const char kPowerButtonPositionField[] = "position";

const char kSideVolumeButtonPath[] = "/ui/side-volume-button";
const char kSideVolumeButtonRegion[] = "region";
const char kSideVolumeButtonSide[] = "side";

const char kHardwarePropertiesPath[] = "/hardware-properties";
const char kStylusCategoryField[] = "stylus-category";
const char kDisplayCategoryField[] = "display-type";

constexpr char kFingerprintPath[] = "/fingerprint";
constexpr char kFingerprintSensorLocationField[] = "sensor-location";

constexpr char kArcScalePath[] = "/arc";
constexpr char kArcScaleProperty[] = "scale";

constexpr char kInstantTetheringPath[] = "/cross-device/instant-tethering";
constexpr char kDisableInstantTetheringProperty[] = "disable-instant-tethering";

constexpr char kOzoneNNPalmPropertiesPath[] = "/nnpalm";
constexpr char kOzoneNNPalmCompatibleProperty[] = "touch-compatible";
constexpr char kOzoneNNPalmRadiusProperty[] = "radius-polynomial";
constexpr std::array<const char*, 2> kOzoneNNPalmOptionalProperties = {
    kOzoneNNPalmCompatibleProperty, kOzoneNNPalmRadiusProperty};

constexpr char kArcBuildPropertiesPath[] = "/arc/build-properties";
constexpr std::array<const char*, 2> kArcBuildProperties = {"device",
                                                            "product"};
constexpr std::array<const char*, 4> kArcOptionalBuildProperties = {
    "first-api-level", "marketing-name", "metrics-tag", "pai-regions"};

const char kPowerPath[] = "/power";
const char kAllowAmbientEQField[] = "allow-ambient-eq";
const char kAllowAmbientEQFeature[] = "AllowAmbientEQ";

constexpr char kEnableCrashpadFlag[] = "--enable-crashpad";
constexpr char kEnableBreakpadFlag[] = "--no-enable-crashpad";

// These hashes are only being used temporarily till we can determine if a
// device is a Chromebox for Meetings or not from the Install Time attributes.
// TODO(rkc, pbos): Remove these and related code once crbug.com/706523 is
// fixed.
const char* kChromeboxForMeetingAppIdHashes[] = {
    "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB",
    "A3BC37E2148AC4E99BE4B16AF9D42DD1E592BBBE",
    "1C93BD3CF875F4A73C0B2A163BB8FBDA8B8B3D80",
    "307E96539209F95A1A8740C713E6998A73657D96",
    "4F25792AF1AA7483936DE29C07806F203C7170A0",
    "BD8781D757D830FC2E85470A1B6E8A718B7EE0D9",
    "4AC2B6C63C6480D150DFDA13E4A5956EB1D0DDBB",
    "81986D4F846CEDDDB962643FA501D1780DD441BB",
};

namespace {

// Path to file containing developer-supplied modifications to Chrome's
// environment and command line. Passed to
// ChromiumCommandBuilder::ApplyUserConfig().
const char kChromeDevConfigPath[] = "/etc/chrome_dev.conf";

// Returns a base::FilePath corresponding to the DATA_DIR environment variable.
base::FilePath GetDataDir(ChromiumCommandBuilder* builder) {
  return base::FilePath(builder->ReadEnvVar("DATA_DIR"));
}

// Returns a base::FilePath corresponding to the subdirectory of DATA_DIR where
// user data is stored.
base::FilePath GetUserDir(ChromiumCommandBuilder* builder) {
  return base::FilePath(GetDataDir(builder).Append("user"));
}

// Enables the "AutoNightLight" feature if "auto-night-light" is set to "True"
// in cros_config.
void SetUpAutoNightLightFlag(ChromiumCommandBuilder* builder,
                             brillo::CrosConfigInterface* cros_config) {
  std::string auto_night_light_str;
  if (!cros_config ||
      !cros_config->GetString("/", "auto-night-light", &auto_night_light_str)) {
    return;
  }

  if (auto_night_light_str != "true")
    return;

  builder->AddFeatureEnableOverride("AutoNightLight");
}

// Called by AddUiFlags() to take a wallpaper flag type ("default" or "guest"
// or "child") and file type (e.g. "child", "default", "oem", "guest") and
// add the corresponding flags to |builder| if the files exist. Returns false
// if the files don't exist.
bool AddWallpaperFlags(
    ChromiumCommandBuilder* builder,
    const std::string& flag_type,
    const std::string& file_type,
    base::Callback<bool(const base::FilePath&)> path_exists) {
  const base::FilePath large_path(base::StringPrintf(
      "/usr/share/chromeos-assets/wallpaper/%s_large.jpg", file_type.c_str()));
  const base::FilePath small_path(base::StringPrintf(
      "/usr/share/chromeos-assets/wallpaper/%s_small.jpg", file_type.c_str()));
  if (!path_exists.Run(large_path) || !path_exists.Run(small_path)) {
    LOG(WARNING) << "Could not find both paths: " << large_path.MaybeAsASCII()
                 << " and " << small_path.MaybeAsASCII();
    return false;
  }

  builder->AddArg(base::StringPrintf("--%s-wallpaper-large=%s",
                                     flag_type.c_str(),
                                     large_path.value().c_str()));
  builder->AddArg(base::StringPrintf("--%s-wallpaper-small=%s",
                                     flag_type.c_str(),
                                     small_path.value().c_str()));
  return true;
}

// Adds ARC related flags.
void AddArcFlags(ChromiumCommandBuilder* builder,
                 std::set<std::string>* disallowed_params_out,
                 brillo::CrosConfigInterface* cros_config) {
  if (builder->UseFlagIsSet("arc") ||
      (builder->UseFlagIsSet("cheets") && builder->is_test_build())) {
    builder->AddArg("--arc-availability=officially-supported");
  } else if (builder->UseFlagIsSet("cheets")) {
    builder->AddArg("--arc-availability=installed");
  } else {
    // Don't pass ARC availability related flags in chrome_dev.conf to Chrome if
    // ARC is not installed at all.
    disallowed_params_out->insert("--arc-availability");
    disallowed_params_out->insert("--enable-arc");
    disallowed_params_out->insert("--arc-available");
    disallowed_params_out->insert("-arc-availability");
    disallowed_params_out->insert("-enable-arc");
    disallowed_params_out->insert("-arc-available");
  }

  if (builder->UseFlagIsSet("arc_adb_sideloading"))
    builder->AddFeatureEnableOverride("ArcAdbSideloading");
  if (builder->UseFlagIsSet("arc_transition_m_to_n"))
    builder->AddArg("--arc-transition-migration-required");
  if (builder->UseFlagIsSet("arc_force_2x_scaling"))
    builder->AddArg("--force-remote-shell-scale=2");
  if (builder->UseFlagIsSet("arcvm") && !builder->UseFlagIsSet("arcpp"))
    builder->AddArg("--enable-arcvm");
  // Devices of tablet form factor will have special app behaviour.
  if (builder->UseFlagIsSet("tablet_form_factor"))
    builder->AddArg("--enable-tablet-form-factor");

  std::string arc_scale;
  if (cros_config &&
      cros_config->GetString(kArcScalePath, kArcScaleProperty, &arc_scale)) {
    builder->AddArg("--arc-scale=" + arc_scale);
  }

  // Pass USE flags of ARM binary translation libraries to Chrome.
  if (builder->UseFlagIsSet("houdini"))
    builder->AddArg("--enable-houdini");
  if (builder->UseFlagIsSet("houdini64"))
    builder->AddArg("--enable-houdini64");
  if (builder->UseFlagIsSet("ndk_translation"))
    builder->AddArg("--enable-ndk-translation");
  if (builder->UseFlagIsSet("ndk_translation64"))
    builder->AddArg("--enable-ndk-translation64");
  if (builder->UseFlagIsSet("arc_native_bridge_64bit_support_experiment"))
    builder->AddArg("--arc-enable-native-bridge-64bit-support-experiment");
}

void AddCrostiniFlags(ChromiumCommandBuilder* builder) {
  if (builder->UseFlagIsSet("kvm_host")) {
    builder->AddFeatureEnableOverride("Crostini");
  }
  if (builder->UseFlagIsSet("virtio_gpu")) {
    builder->AddFeatureEnableOverride("CrostiniGpuSupport");
  }
  if (builder->UseFlagIsSet("dlc")) {
    builder->AddFeatureEnableOverride("CrostiniEnableDlc");
  }
  if (builder->UseFlagIsSet("kvm_transition")) {
    builder->AddArg("--kernelnext-restrict-vms");
  }
}

void AddPluginVmFlags(ChromiumCommandBuilder* builder) {
  if (builder->UseFlagIsSet("pita")) {
    builder->AddFeatureEnableOverride("PluginVm");
  }
  if (builder->UseFlagIsSet("pita-camera")) {
    builder->AddFeatureEnableOverride("PluginVmShowCameraPermissions");
  }
  if (builder->UseFlagIsSet("pita-microphone")) {
    builder->AddFeatureEnableOverride("PluginVmShowMicrophonePermissions");
  }
}

void AddBorealisFlags(ChromiumCommandBuilder* builder) {
  if (builder->UseFlagIsSet("borealis_host")) {
    builder->AddFeatureEnableOverride("Borealis");
  }
}

void AddLacrosFlags(ChromiumCommandBuilder* builder) {
  if (builder->UseFlagIsSet("lacros"))
    builder->AddFeatureEnableOverride("LacrosSupport");
}

// Ensures that necessary directory exist with the correct permissions and sets
// related arguments and environment variables.
void CreateDirectories(ChromiumCommandBuilder* builder) {
  const uid_t uid = builder->uid();
  const gid_t gid = builder->gid();
  const uid_t kRootUid = 0;
  const gid_t kRootGid = 0;

  const base::FilePath data_dir = GetDataDir(builder);
  builder->AddArg("--user-data-dir=" + data_dir.value());

  const base::FilePath user_dir = GetUserDir(builder);
  CHECK(EnsureDirectoryExists(user_dir, uid, gid, 0755));
  // TODO(keescook): Remove Chrome's use of $HOME.
  builder->AddEnvVar("HOME", user_dir.value());

  // Old builds will have a profile dir that's owned by root; newer ones won't
  // have this directory at all.
  CHECK(EnsureDirectoryExists(data_dir.Append("Default"), uid, gid, 0755));

  const base::FilePath state_dir("/run/state");
  CHECK(base::DeleteFile(state_dir, true));
  CHECK(EnsureDirectoryExists(state_dir, kRootUid, kRootGid, 0710));

  // Create a directory where the session manager can store a copy of the user
  // policy key, that will be readable by the chrome process as chronos.
  const base::FilePath policy_dir("/run/user_policy");
  CHECK(base::DeleteFile(policy_dir, true));
  CHECK(EnsureDirectoryExists(policy_dir, kRootUid, gid, 0710));

  // Create a directory where the chrome process can store a reboot request so
  // that it persists across browser crashes but is always removed on reboot.
  // This directory also houses the wayland and arc-bridge sockets that are
  // exported to VMs and Android.
  CHECK(EnsureDirectoryExists(base::FilePath("/run/chrome"), uid, gid, 0755));

  // Ensure the existence of the directory in which the whitelist and other
  // ownership-related state will live. Yes, it should be owned by root. The
  // permissions are set such that the policy-readers group can see the content
  // of known files inside whitelist. The policy-readers group is composed of
  // the chronos user and other daemon accessing the device policies but not
  // anything else.
  gid_t policy_readers_gid;
  CHECK(brillo::userdb::GetGroupInfo("policy-readers", &policy_readers_gid));
  CHECK(EnsureDirectoryExists(base::FilePath("/var/lib/whitelist"), kRootUid,
                              policy_readers_gid, 0750));

  // Create the directory where policies for extensions installed in
  // device-local accounts are cached. This data is read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/device_local_account_component_policy"), uid,
      gid, 0700));

  // Create the directory where external data referenced by policies is cached
  // for device-local accounts. This data is read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/device_local_account_external_policy_data"),
      uid, gid, 0700));

  // Create the directory where external data referenced by device policy is
  // cached. This data is read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/device_policy_external_data"), uid, gid,
      0700));

  // Create the directory where the AppPack extensions are cached.
  // These extensions are read and written by chronos.
  CHECK(EnsureDirectoryExists(base::FilePath("/var/cache/app_pack"), uid, gid,
                              0700));

  // Create the directory where extensions for device-local accounts are cached.
  // These extensions are read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/device_local_account_extensions"), uid, gid,
      0700));

  // Create the directory where the Quirks Client can store downloaded
  // icc and other display profiles.
  CHECK(EnsureDirectoryExists(base::FilePath("/var/cache/display_profiles"),
                              uid, gid, 0700));

  // Create the directory for shared installed extensions.
  // Shared extensions are validated at runtime by the browser.
  // These extensions are read and written by chronos.
  CHECK(EnsureDirectoryExists(base::FilePath("/var/cache/shared_extensions"),
                              uid, gid, 0700));

  // Create the directory where policies for extensions installed in the
  // sign-in profile are cached. This data is read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/signin_profile_component_policy"), uid, gid,
      0700));

  // Create the directory where extensions for the sign-in profile are cached.
  // This data is read and written by chronos.
  CHECK(EnsureDirectoryExists(
      base::FilePath("/var/cache/signin_profile_extensions"), uid, gid, 0700));

  // Tell Chrome where to write logging messages before the user logs in.
  base::FilePath system_log_dir("/var/log/chrome");
  CHECK(EnsureDirectoryExists(system_log_dir, uid, gid, 0755));
  builder->AddEnvVar("CHROME_LOG_FILE",
                     system_log_dir.Append("chrome").value());

  // Log directory for the user session. Note that the user dir won't be mounted
  // until later (when the cryptohome is mounted), so we don't create
  // CHROMEOS_SESSION_LOG_DIR here.
  builder->AddEnvVar("CHROMEOS_SESSION_LOG_DIR",
                     user_dir.Append("log").value());

  // Disable Mesa's internal shader disk caching feature, since Chrome has its
  // own shader cache implementation and the GPU process sandbox does not
  // allow threads (Mesa uses threads for this feature).
  builder->AddEnvVar("MESA_GLSL_CACHE_DISABLE", "true");

  // On devices with Chrome OS camera HAL, Chrome needs to host the unix domain
  // named socket /run/camera/camera3.sock to provide the camera HAL Mojo
  // service to the system.
  if (base::PathExists(base::FilePath("/usr/bin/cros_camera_service"))) {
    // The socket is created and listened on by Chrome, and receives connections
    // from the camera HAL v3 process and cameraserver process in Android
    // container which run as group arc-camera.  In addition, the camera HAL v3
    // process also hosts a unix domain named socket in /run/camera for the
    // sandboxed camera library process.  Thus the directory is created with
    // user chronos and group arc-camera with 0770 permission.
    gid_t arc_camera_gid;
    CHECK(brillo::userdb::GetGroupInfo("arc-camera", &arc_camera_gid));
    CHECK(EnsureDirectoryExists(base::FilePath("/run/camera"), uid,
                                arc_camera_gid, 0770));
    // This directory stores the tokens used for identification of camera HAL
    // clients. Clients would read from this directory to retrieve their
    // respective tokens. Untrusted clients such as pluginvm clients would only
    // have access to a subdirectory inside to limit their access.
    CHECK(EnsureDirectoryExists(base::FilePath("/run/camera_tokens"), uid,
                                arc_camera_gid, 0770));
    // The /var/cache/camera folder is used to store camera-related configs and
    // settings that are either extracted from Android container, or generated
    // by the camera HAL at runtime.
    CHECK(EnsureDirectoryExists(base::FilePath("/var/cache/camera"), uid,
                                arc_camera_gid, 0770));
  }

  // On devices with CUPS proxy daemon, Chrome needs to create the directory so
  // cups_proxy can host a unix domain named socket at
  // /run/cups_proxy/cups_proxy.sock
  if (base::PathExists(base::FilePath("/usr/bin/cups_proxy"))) {
    uid_t cups_proxy_uid;
    gid_t cups_proxy_gid;
    CHECK(brillo::userdb::GetUserInfo("cups-proxy", &cups_proxy_uid,
                                      &cups_proxy_gid));
    // TODO(pihsun): Check if this permission is good. We need to add the
    // client accessing this to cups_proxy group for this to work.
    CHECK(EnsureDirectoryExists(base::FilePath("/run/cups_proxy"),
                                cups_proxy_uid, cups_proxy_gid, 0770));
  }
}

// Adds system-related flags to the command line.
void AddSystemFlags(ChromiumCommandBuilder* builder) {
  const base::FilePath data_dir = GetDataDir(builder);

  // We need to delete these files as Chrome may have left them around from its
  // prior run (if it crashed).
  base::DeleteFile(data_dir.Append("SingletonLock"), false);
  base::DeleteFile(data_dir.Append("SingletonSocket"), false);

  // Some targets (embedded, VMs) do not need component updates.
  if (!builder->UseFlagIsSet("compupdates"))
    builder->AddArg("--disable-component-update");

  if (builder->UseFlagIsSet("smartdim"))
    builder->AddFeatureEnableOverride("SmartDim");

  // On developer systems, set a flag to let the browser know.
  if (builder->is_developer_end_user())
    builder->AddArg("--system-developer-mode");

  if (builder->UseFlagIsSet("diagnostics"))
    builder->AddFeatureEnableOverride("UmaStorageDimensions");

  // Enable Wilco only features.
  if (builder->UseFlagIsSet("wilco")) {
    builder->AddFeatureEnableOverride("WilcoDtc");
    // Needed for scheduled update checks on Wilco.
    builder->AddArg("--register-max-dark-suspend-delay");
  }

  // Some platforms have SMT enabled by default.
  if (builder->UseFlagIsSet("scheduler_configuration_performance"))
    builder->AddArg("--scheduler-configuration-default=performance");

  if (builder->UseFlagIsSet("enable_neural_palm_detection_filter"))
    builder->AddFeatureEnableOverride("EnableNeuralPalmDetectionFilter");

  if (builder->UseFlagIsSet("enable_heuristic_palm_detection_filter"))
    builder->AddFeatureEnableOverride("EnableHeuristicPalmDetectionFilter");

  if (builder->UseFlagIsSet("ondevice_handwriting"))
    builder->AddArg("--ondevice_handwriting=use_rootfs");
  else if (builder->UseFlagIsSet("ondevice_handwriting_dlc"))
    builder->AddArg("--ondevice_handwriting=use_dlc");
}

// Adds UI-related flags to the command line.
void AddUiFlags(ChromiumCommandBuilder* builder,
                brillo::CrosConfigInterface* cros_config) {
  const base::FilePath data_dir = GetDataDir(builder);

  // Force OOBE on test images that have requested it.
  if (base::PathExists(base::FilePath("/root/.test_repeat_oobe"))) {
    base::DeleteFile(data_dir.Append(".oobe_completed"), false);
    base::DeleteFile(data_dir.Append("Local State"), false);
  }

  // Disable logging redirection on test images to make debugging easier.
  if (builder->is_test_build())
    builder->AddArg("--disable-logging-redirect");

  if (builder->UseFlagIsSet("cfm_enabled_device") &&
      builder->UseFlagIsSet("screenshare_sw_codec")) {
    builder->AddFeatureEnableOverride("WebRtcScreenshareSwEncoding");
  }

  if (builder->UseFlagIsSet("touch_centric_device")) {
    // Tapping the power button should turn the screen off in laptop mode.
    builder->AddArg("--force-tablet-power-button");
    // Show touch centric OOBE screens during the first user run in laptop mode.
    builder->AddArg("--oobe-force-tablet-first-run");
  }

  if (builder->UseFlagIsSet("rialto")) {
    builder->AddArg("--enterprise-enable-zero-touch-enrollment=hands-off");
    builder->AddArg("--disable-machine-cert-request");
    builder->AddArg("--cellular-first");
    builder->AddArg(
        "--app-mode-oem-manifest=/etc/rialto_overlay_oem_manifest.json");
    builder->AddArg("--log-level=0");
    builder->AddArg("--disable-logging-redirect");
  }

  builder->AddArg("--login-manager");
  builder->AddArg("--login-profile=user");

  if (builder->UseFlagIsSet("natural_scroll_default"))
    builder->AddArg("--enable-natural-scroll-default");
  if (!builder->UseFlagIsSet("legacy_keyboard"))
    builder->AddArg("--has-chromeos-keyboard");
  if (builder->UseFlagIsSet("legacy_power_button"))
    builder->AddArg("--aura-legacy-power-button");
  if (builder->UseFlagIsSet("touchview"))
    builder->AddArg("--enable-touchview");
  if (builder->UseFlagIsSet("touchscreen_wakeup"))
    builder->AddArg("--touchscreen-usable-while-screen-off");
  if (builder->UseFlagIsSet("oobe_skip_to_login"))
    builder->AddArg("--oobe-skip-to-login");
  if (builder->UseFlagIsSet("oobe_skip_postlogin"))
    builder->AddArg("--oobe-skip-postlogin");

  if (builder->UseFlagIsSet("disable_background_blur"))
    builder->AddFeatureDisableOverride("EnableBackgroundBlur");

  if (builder->UseFlagIsSet("disable_explicit_dma_fences"))
    builder->AddArg("--disable-explicit-dma-fences");

  if (builder->UseFlagIsSet("shelf-hotseat"))
    builder->AddFeatureEnableOverride("ShelfHotseat");

  if (builder->UseFlagIsSet("webui-tab-strip")) {
    builder->AddFeatureEnableOverride("WebUITabStrip");
    builder->AddFeatureEnableOverride("WebUITabStripTabDragIntegration");
  }

  SetUpAutoDimFlag(builder, cros_config);

  SetUpWallpaperFlags(builder, cros_config, base::Bind(base::PathExists));

  // TODO(yongjaek): Remove the following flag when the kiosk mode app is ready
  // at crbug.com/309806.
  if (builder->UseFlagIsSet("moblab"))
    builder->AddArg("--disable-demo-mode");

  if (builder->UseFlagIsSet("allow_consumer_kiosk"))
    builder->AddArg("--enable-consumer-kiosk");

  if (builder->UseFlagIsSet("biod"))
    builder->AddFeatureEnableOverride("QuickUnlockFingerprint");

  if (builder->UseFlagIsSet("clear_fast_ink_buffer"))
    builder->AddArg("--ash-clear-fast-ink-buffer");

  SetUpPowerButtonPositionFlag(builder, cros_config);
  SetUpSideVolumeButtonPositionFlag(builder, cros_config);
  SetUpRegulatoryLabelFlag(builder, cros_config);
  SetUpInternalStylusFlag(builder, cros_config);
  SetUpFingerprintSensorLocationFlag(builder, cros_config);
  SetUpOzoneNNPalmPropertiesFlag(builder, cros_config);
  SetUpArcBuildPropertiesFlag(builder, cros_config);
  SetUpAutoNightLightFlag(builder, cros_config);
  SetUpAllowAmbientEQFlag(builder, cros_config);
  SetUpInstantTetheringFlag(builder, cros_config);
}

// Adds enterprise-related flags to the command line.
void AddEnterpriseFlags(ChromiumCommandBuilder* builder) {
  builder->AddArg("--enterprise-enrollment-initial-modulus=15");
  builder->AddArg("--enterprise-enrollment-modulus-limit=19");
}

// Adds patterns to the --vmodule flag.
void AddVmodulePatterns(ChromiumCommandBuilder* builder) {
  // Turn on logging about external displays being connected and disconnected.
  // Different behavior is seen from different displays and these messages are
  // used to determine what happened within feedback reports.
  builder->AddVmodulePattern("*/ui/display/manager/chromeos/*=1");

  // Turn on basic logging for Ozone platform implementations.
  builder->AddVmodulePattern("*/ui/ozone/*=1");

  // Turn on basic logging for enrollment flow.
  builder->AddVmodulePattern("*/browser/chromeos/login/enrollment/*=1");
  builder->AddVmodulePattern("enrollment_screen_handler=1");

  // TODO(https://crbug.com/907158): Needed for investigating issues with tablet
  // mode detection and internal input device event blocking logic.
  builder->AddVmodulePattern("*/ash/wm/tablet_mode/*=1");

  // TODO(https://crbug.com/943790): Remove after model development is complete.
  builder->AddVmodulePattern("*/chromeos/power/auto_screen_brightness/*=1");

  // TODO(https://crbug.com/1106586,https://crbug.com/1102123): Remove after
  // issues with night light are closed.
  builder->AddVmodulePattern("*night_light*=1");

  if (builder->UseFlagIsSet("cheets"))
    builder->AddVmodulePattern("*arc/*=1");
}

}  // namespace

void AddSerializedAshFlags(ChromiumCommandBuilder* builder,
                           brillo::CrosConfigInterface* cros_config) {
  using std::string_literals::operator""s;
  std::string serialized_ash_flags;

  if (!cros_config->GetString(kUiPath, kSerializedAshFlagsProperty,
                              &serialized_ash_flags)) {
    return;
  }

  for (const auto& flag :
       base::SplitString(serialized_ash_flags, "\0"s, base::KEEP_WHITESPACE,
                         base::SPLIT_WANT_NONEMPTY)) {
    builder->AddArg(flag);
  }
}

void SetUpRegulatoryLabelFlag(ChromiumCommandBuilder* builder,
                              brillo::CrosConfigInterface* cros_config) {
  std::string subdir;
  if (cros_config &&
      cros_config->GetString("/", kRegulatoryLabelProperty, &subdir)) {
    builder->AddArg("--regulatory-label-dir=" + subdir);
  }
}

void SetUpWallpaperFlags(
    ChromiumCommandBuilder* builder,
    brillo::CrosConfigInterface* cros_config,
    base::Callback<bool(const base::FilePath&)> path_exists) {
  AddWallpaperFlags(builder, "guest", "guest", path_exists);
  AddWallpaperFlags(builder, "child", "child", path_exists);

  // Use the configuration if available.
  std::string filename;
  if (cros_config &&
      cros_config->GetString("/", kWallpaperProperty, &filename) &&
      AddWallpaperFlags(builder, "default", filename, path_exists)) {
    // If there's a wallpaper defined in cros config, mark this as an OEM
    // wallpaper.
    builder->AddArg("--default-wallpaper-is-oem");
    return;
  }

  // Fall back to oem.
  if (AddWallpaperFlags(builder, "default", "oem", path_exists)) {
    builder->AddArg("--default-wallpaper-is-oem");
    return;
  }

  // Fall back to default.
  AddWallpaperFlags(builder, "default", "default", path_exists);
}

void SetUpInternalStylusFlag(ChromiumCommandBuilder* builder,
                             brillo::CrosConfigInterface* cros_config) {
  std::string stylus_category;
  if (cros_config &&
      cros_config->GetString(kHardwarePropertiesPath, kStylusCategoryField,
                             &stylus_category) &&
      stylus_category == "internal") {
    builder->AddArg("--has-internal-stylus");
  }
}

void SetUpFingerprintSensorLocationFlag(
    ChromiumCommandBuilder* builder, brillo::CrosConfigInterface* cros_config) {
  std::string fingerprint_sensor_location;
  if (!cros_config ||
      !cros_config->GetString(kFingerprintPath, kFingerprintSensorLocationField,
                              &fingerprint_sensor_location)) {
    return;
  }

  if (fingerprint_sensor_location != "none") {
    builder->AddArg(base::StringPrintf("--fingerprint-sensor-location=%s",
                                       fingerprint_sensor_location.c_str()));
  }
}

void SetUpAutoDimFlag(ChromiumCommandBuilder* builder,
                      brillo::CrosConfigInterface* cros_config) {
  std::string display_type;
  if (cros_config &&
      cros_config->GetString(kHardwarePropertiesPath, kDisplayCategoryField,
                             &display_type) &&
      display_type == "old") {
    builder->AddArg("--enable-dim-shelf");
  }
}

void SetUpPowerButtonPositionFlag(ChromiumCommandBuilder* builder,
                                  brillo::CrosConfigInterface* cros_config) {
  std::string edge_as_string, position_as_string;
  if (!cros_config ||
      !cros_config->GetString(kPowerButtonPositionPath, kPowerButtonEdgeField,
                              &edge_as_string) ||
      !cros_config->GetString(kPowerButtonPositionPath,
                              kPowerButtonPositionField, &position_as_string)) {
    return;
  }

  double position_as_double = 0;
  if (!base::StringToDouble(position_as_string, &position_as_double)) {
    LOG(ERROR) << "Invalid value for power button position: "
               << position_as_string;
    return;
  }

  base::Value position_info(base::Value::Type::DICTIONARY);
  position_info.SetStringKey(kPowerButtonEdgeField, std::move(edge_as_string));
  position_info.SetDoubleKey(kPowerButtonPositionField, position_as_double);

  std::string json_position_info;
  base::JSONWriter::Write(position_info, &json_position_info);
  builder->AddArg(base::StringPrintf("--ash-power-button-position=%s",
                                     json_position_info.c_str()));
}

void SetUpSideVolumeButtonPositionFlag(
    ChromiumCommandBuilder* builder, brillo::CrosConfigInterface* cros_config) {
  std::string region_as_string, side_as_string;
  if (!cros_config ||
      !cros_config->GetString(kSideVolumeButtonPath, kSideVolumeButtonRegion,
                              &region_as_string) ||
      !cros_config->GetString(kSideVolumeButtonPath, kSideVolumeButtonSide,
                              &side_as_string)) {
    return;
  }

  base::Value position_info(base::Value::Type::DICTIONARY);
  position_info.SetStringKey(kSideVolumeButtonRegion,
                             std::move(region_as_string));
  position_info.SetStringKey(kSideVolumeButtonSide, std::move(side_as_string));

  std::string json_position_info;
  if (!base::JSONWriter::Write(position_info, &json_position_info)) {
    LOG(ERROR) << "JSONWriter::Write failed in writing side volume button "
               << "position info.";
    return;
  }
  builder->AddArg("--ash-side-volume-button-position=" + json_position_info);
}

void SetUpOzoneNNPalmPropertiesFlag(ChromiumCommandBuilder* builder,
                                    brillo::CrosConfigInterface* cros_config) {
  base::Value info(base::Value::Type::DICTIONARY);
  if (cros_config) {
    std::string value;
    for (const char* property : kOzoneNNPalmOptionalProperties) {
      if (cros_config->GetString(kOzoneNNPalmPropertiesPath, property,
                                 &value)) {
        info.SetStringKey(property, std::move(value));
        continue;
      }
    }
  }

  std::string json_info;
  if (!base::JSONWriter::Write(info, &json_info)) {
    LOG(ERROR)
        << "JSONWriter::Write failed in writing Ozone NNPalm properties.";
    return;
  }
  builder->AddArg("--ozone-nnpalm-properties=" + json_info);
}

void SetUpArcBuildPropertiesFlag(ChromiumCommandBuilder* builder,
                                 brillo::CrosConfigInterface* cros_config) {
  base::Value info(base::Value::Type::DICTIONARY);
  if (cros_config) {
    std::string value;
    for (const char* property : kArcBuildProperties) {
      if (cros_config->GetString(kArcBuildPropertiesPath, property, &value)) {
        info.SetStringKey(property, std::move(value));
        continue;
      }
      LOG(ERROR) << property << " is not found in cros config";
    }
    for (const char* property : kArcOptionalBuildProperties) {
      if (cros_config->GetString(kArcBuildPropertiesPath, property, &value))
        info.SetStringKey(property, std::move(value));
    }
  }

  std::string json_info;
  if (!base::JSONWriter::Write(info, &json_info)) {
    LOG(ERROR)
        << "JSONWriter::Write failed in writing ARC build properties info";
    return;
  }
  builder->AddArg("--arc-build-properties=" + json_info);
}

// Enables the "AllowAmbientEQ" feature if "allow-ambient-eq" is set to "1"
// in cros_config.
void SetUpAllowAmbientEQFlag(ChromiumCommandBuilder* builder,
                             brillo::CrosConfigInterface* cros_config) {
  std::string allow_ambient_eq_str;
  if (!cros_config || !cros_config->GetString(kPowerPath, kAllowAmbientEQField,
                                              &allow_ambient_eq_str)) {
    return;
  }

  if (allow_ambient_eq_str != "1")
    return;

  builder->AddFeatureEnableOverride("AllowAmbientEQ");
}

void SetUpInstantTetheringFlag(ChromiumCommandBuilder* builder,
                               brillo::CrosConfigInterface* cros_config) {
  if (builder->UseFlagIsSet("disable_instant_tethering")) {
    builder->AddFeatureDisableOverride("InstantTethering");
    return;
  }

  std::string disable_instant_tethering_str;
  if (!cros_config || !cros_config->GetString(kInstantTetheringPath,
                                              kDisableInstantTetheringProperty,
                                              &disable_instant_tethering_str)) {
    return;
  }

  if (disable_instant_tethering_str == "true")
    builder->AddFeatureDisableOverride("InstantTethering");
}

void AddCrashHandlerFlag(ChromiumCommandBuilder* builder) {
  builder->AddArg(builder->UseFlagIsSet("force_breakpad")
                      ? kEnableBreakpadFlag
                      : kEnableCrashpadFlag);
}

void PerformChromeSetup(brillo::CrosConfigInterface* cros_config,
                        bool* is_developer_end_user_out,
                        std::map<std::string, std::string>* env_vars_out,
                        std::vector<std::string>* args_out,
                        uid_t* uid_out) {
  DCHECK(env_vars_out);
  DCHECK(args_out);
  DCHECK(uid_out);

  ChromiumCommandBuilder builder;
  std::set<std::string> disallowed_prefixes;
  CHECK(builder.Init());
  CHECK(builder.SetUpChromium());

  // Please add new code to the most-appropriate helper function instead of
  // putting it here. Things that apply to all Chromium-derived binaries (e.g.
  // app_shell, content_shell, etc.) rather than just to Chrome belong in the
  // ChromiumCommandBuilder class instead.
  CreateDirectories(&builder);
  AddSerializedAshFlags(&builder, cros_config);
  AddSystemFlags(&builder);
  AddUiFlags(&builder, cros_config);
  AddArcFlags(&builder, &disallowed_prefixes, cros_config);
  AddCrostiniFlags(&builder);
  AddPluginVmFlags(&builder);
  AddBorealisFlags(&builder);
  AddLacrosFlags(&builder);
  AddEnterpriseFlags(&builder);
  AddVmodulePatterns(&builder);
  AddCrashHandlerFlag(&builder);

  // Apply any modifications requested by the developer.
  if (builder.is_developer_end_user()) {
    builder.ApplyUserConfig(base::FilePath(kChromeDevConfigPath),
                            disallowed_prefixes);
  }

  *is_developer_end_user_out = builder.is_developer_end_user();
  *env_vars_out = builder.environment_variables();
  *args_out = builder.arguments();
  *uid_out = builder.uid();

  // Do not add code here. Potentially-expensive work should be done between
  // StartServer() and WaitForServer().
}

}  // namespace login_manager
