# 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() {
    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}"
  }

  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 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

  # 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

  # 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
