# Copyright 2017 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.

description     "Firmware updating task before UI"
author          "chromium-os-dev@chromium.org"

start on starting ui

# This job blocks the start of UI and calls all the tasks sequentially at boot
# if the tasks:
#   1. Show up the boot message by calling `chromeos-boot-alert`.
#   2. Leave the message and enter Chrome UI normally after it is finished.
# Please make sure the tasks running here DO NOT take a long time in the no-op
# case because this job BLOCKS the UI startup.

# It has no main script so that it only runs once at boot before UI starts.
pre-start script
  logit() {
    logger -t "${UPSTART_JOB}" "$@"
  }

  # Update FPMCU firmware.
  FP_SCRIPT='/usr/sbin/bio_fw_updater'
  FP_LOG_DIR='/var/log/biod'
  FP_PRESTART_LOG='/var/log/bio_fw_updater.out'

  do_update_fp_firmware() {
    # TODO (b/177385048): skip FPMCU fw update on voema for now.
    model="$(cros_config / name)"
    if [ "${model}" = "voema" ]; then
      logit "Skip FPMCU firmware update on model ${model}."
    else
      mkdir -p "${FP_LOG_DIR}"
      logit "Update FPMCU firmware."
      "${FP_SCRIPT}" "--log_dir=${FP_LOG_DIR}" >"${FP_PRESTART_LOG}" 2>&1 || \
        logit "Failed to update FPMCU firmware."
      logit "-f" "${FP_PRESTART_LOG}"
    fi
  }

  FACTORY_UTILS="/usr/share/cros/factory_utils.sh"

  FACTORY_MODE=0
  if [ -f "${FACTORY_UTILS}" ]; then
    . "${FACTORY_UTILS}"
    if is_factory_test_mode; then
      FACTORY_MODE=1
    fi
  fi

  if [ -e "${FP_SCRIPT}" ]; then
    if [ ${FACTORY_MODE} -eq 1 ]; then
      logit "Skip FPMCU firmware update in factory mode."
    else
      do_update_fp_firmware
    fi
  fi

  # Update CSME firmware.
  CSME_SCRIPT='/opt/google/csme/scripts/chromeos-csme-update.sh'
  if [ -e "${CSME_SCRIPT}" ]; then
    logit "Update CSME firmware."
    "${CSME_SCRIPT}" || logit "Failed to update CSME firmware."
  fi

  # Update detachable keyboard firmware.
  HAMMERD_SCRIPT='/usr/share/cros/init/hammerd-at-boot.sh'
  if [ -e "${HAMMERD_SCRIPT}" ]; then
    logit "Update keyboard firmware."
    "${HAMMERD_SCRIPT}" || logit "Failed to update keyboard firmware."
  fi

  # Update touch firmware.
  TOUCH_SCRIPT='/opt/google/touch/scripts/chromeos-touch-update.sh'
  if [ -e "${TOUCH_SCRIPT}" ]; then
    logit "Update touch firmware."
    "${TOUCH_SCRIPT}" || logit "Failed to update touch firmware."
  fi

  # Update fwupd firmware.
  FWUPD_SCRIPT='/usr/share/cros/init/fwupd-at-boot.sh'
  if [ -e "${FWUPD_SCRIPT}" ]; then
    logit "Update fwupd firmware."
    "${FWUPD_SCRIPT}" || logit "Failed to update fwupd firmware."
  fi

  # Update TCON (display timing controller) firmware.
  TCON_SCRIPT='/opt/google/tcon/scripts/chromeos-tcon-update.sh'
  if [ -e "${TCON_SCRIPT}" ]; then
    logit "Update TCON firmware."
    "${TCON_SCRIPT}" || logit "Failed to update TCON firmware."
  fi

  # Some firmware updaters require a reboot immediately after the update. This
  # checks if one of them has created a file /tmp/force_reboot_after_fw_update.
  # If yes, and we're not booting from a removable device, then reboot.
  . /usr/share/misc/chromeos-common.sh
  . /usr/sbin/write_gpt.sh

  # Check if rootfs is mounted on a removable device.
  rootdev_removable() {
    load_base_vars

    local dst_drive="$(get_fixed_dst_drive)"
    local root_drive="$(rootdev -s -d)"

    if [ -z  "${dst_drive}" ]; then
      logit "no known device"
    elif [ "${dst_drive}" != "${root_drive}" ]; then
      logit "running on removable device ${dst_drive}, not ${root_drive}"
      return 0
    else
      logit "running on disk ${root_drive}"
    fi
    return 1
  }

  # Do a cold reset.
  do_cold_reset() {
    sync
    # Sleep for hardware to flush physical cache. Otherwise fs metadata may be
    # corrupted.
    sleep 5
    ectool reboot_ec cold
    # Sleep instead of exiting immediately. This long annoying sleep is just for
    # safety until the cold reboot kicks in.
    sleep 60
    exit 0
  }

  COLD_BOOT_FILE="/tmp/force_cold_boot_after_fw_update"
  REBOOT_FILE="/tmp/force_reboot_after_fw_update"
  if [ -e "${COLD_BOOT_FILE}" ]; then
    # Immediately delete the file to avoid bootloops.
    rm -f "${COLD_BOOT_FILE}"
    do_cold_reset
  elif [ -e "${REBOOT_FILE}" ]; then
    # Immediately delete the file to avoid bootloops.
    rm -f "${REBOOT_FILE}"
    # If we're *not* booting from a removable device, then reboot the device.
    if rootdev_removable; then
      logit "rootfs on removable device, not rebooting"
    else
      logit "reboot required"
      reboot
      exit 0
    fi
  fi

  display_boot_message action restore_frecon
end script
