blob: f3ee87883646a1b862562be10d9c05630296a61d [file] [log] [blame]
# 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 "Hammer firmware updater task"
author "chromium-os-dev@chromium.org"
# When the hammer device is plugged, udev emits hammer-device-added signal.
# The example rule file: hammerd/udev/99-hammerd.rules.example
# Additionally, start hammerd when ash gets initialized. Ash observes
# signals from hammerd and, if needed, notifies the user of connected hammer
# state. This means that hammerd should be rerun to ensure ash has received
# relavant signals, in case ash missed signals emitted when hammer device was
# added (e.g. if ash had restarted after hammer device addition due to user
# session restart).
# NOTE: ash-initialized signal is emitted by session manager on request from
# the browser process once ash initialization completes.
start on hammer-device-added or ash-initialized
# If the device pairs correctly, expose hammer's sysfs path for other
# applications to use. Store sysfs path file in a separate directory
# to allow for metrics sandboxing.
env WRITE_SYSFS_PATH="/run/metrics/external/hammer/hammer_sysfs_path"
# Arguments should be empty here and overridden at `hammerd.override`.
env EC_IMAGE_PATH=
env TOUCHPAD_IMAGE_PATH=
env VENDOR_ID=
env PRODUCT_ID=
env USB_BUS=
env USB_PORT=
env AUTOSUSPEND_DELAY_MS="1000"
# These variables may be passed when the job gets started from
# hammerd-at-boot.sh.
import AT_BOOT
import UPDATE_IF
# Set the argument to True when triggering at boot.
env AT_BOOT="false"
# The argument to determine the update condition.
# Valid values are "never", "mismatch", and "always".
env UPDATE_IF="never"
task
pre-start script
# Because the upstart job `boot-update-firmware` will force invoking hammerd
# once before UI is started, we need to make sure hammerd isn't invoked by
# udev before boot-update-firmware gets to run.
if [ "${UPSTART_EVENTS}" = 'hammer-device-added' ] && \
! initctl status boot-update-firmware | grep -q "start/running"; then
logger -t hammerd "boot-update-firmware hasn't started yet, ignore."
stop
fi
sysfs_parent_dir="$(dirname "${WRITE_SYSFS_PATH}")"
mkdir -p "${sysfs_parent_dir}"
# Change ownership so that both metrics and hammerd can have write access.
chown hammerd:metrics "${sysfs_parent_dir}"
chmod 770 "${sysfs_parent_dir}"
end script
# Trigger hammerd process.
# Note: minijail0 "-N" argument (cgroup namespace) is only supported on
# kernel >= 3.14. Remove if the hammerd runs on kernel < 3.14.
script
# If reacting to ash-initialized event, verify that the base is actually
# connected before proceeding - hammerd expects the base to be connected,
# which is not guaranteed on ash initialization signal (unlike on
# hammerd-device-added).
if [ "${UPSTART_EVENTS}" = 'ash-initialized' ]; then
HAMMERD_DETECTOR_SCRIPT='/usr/share/cros/init/hammerd-base-detector.sh'
if [ -e "${HAMMERD_DETECTOR_SCRIPT}" ]; then
# Import base_connected function.
. "${HAMMERD_DETECTOR_SCRIPT}"
if ! base_connected "${UPSTART_JOB}"; then
logger -t "${UPSTART_JOB}" \
"Base not connected during ash initialization"
exit 0
fi
else
logger -t hammerd "hammerd-base-detector script not found."
fi
fi
# Adopt chromeos-config.
hammer_name="$(cros_config /detachable-base ec-image-name)"
# If we find the unibuild config, then override the config.
if [ -n "${hammer_name}" ]; then
EC_IMAGE_PATH="/lib/firmware/${hammer_name}"
touch_name="$(cros_config /detachable-base touch-image-name)"
if [ -n "${touch_name}" ]; then
TOUCHPAD_IMAGE_PATH="/lib/firmware/${touch_name}"
fi
VENDOR_ID="$(cros_config /detachable-base vendor-id)"
PRODUCT_ID="$(cros_config /detachable-base product-id)"
USB_PATH="$(cros_config /detachable-base usb-path)"
fi
exit_status=0
/sbin/minijail0 -e -N -p -l -u hammerd -g hammerd -c 0002 \
/usr/bin/hammerd --ec_image_path="${EC_IMAGE_PATH}" \
--touchpad_image_path="${TOUCHPAD_IMAGE_PATH}" \
--vendor_id="${VENDOR_ID}" \
--product_id="${PRODUCT_ID}" \
--usb_path="${USB_PATH}" \
--autosuspend_delay_ms="${AUTOSUSPEND_DELAY_MS}" \
--at_boot="${AT_BOOT}" \
--update_if="${UPDATE_IF}" || exit_status="$?"
if [ "${exit_status}" -eq 0 ]; then
usb_device_path="/sys/bus/usb/devices/${USB_PATH}"
if ! echo "${usb_device_path}" > "${WRITE_SYSFS_PATH}"; then
logger -t ${UPSTART_JOB} \
"FAILED to write into sysfs tag file: ${WRITE_SYSFS_PATH}"
exit 1 # Exit status for "unknown error" in hammerd.
fi
else
rm "${WRITE_SYSFS_PATH}" || true
fi
exit "${exit_status}"
end script