blob: f42b0a0bbc15025ecf6768b0dfb86aed16f0ccd8 [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 "Start Chrome OS camera service"
author "chromium-os-dev@chromium.org"
start on starting system-services or usbcam-device-added or mipicam-device-added
stop on stopping system-services
expect fork
respawn
respawn limit 10 60
env SECCOMP_POLICY_FILE=/usr/share/policy/cros-camera.policy
env UVC_HWTIMESTAMPS_FILE=/sys/module/uvcvideo/parameters/hwtimestamps
env UVC_CLOCK_FILE=/sys/module/uvcvideo/parameters/clock
env SERVER_TOKEN_DIR=/run/camera_tokens/server
# Don't respawn too aggressively so kernel has some room to breathe and
# initialize cameras.
env RESPAWN_DELAY=5
# cros_camera_service provides camera service to both Chrome and ARC++:
# Chrome hosts the CameraHalDispatcher Mojo proxy; cros_camera_service forks a
# child process to host the camera HAL adapter and registers to
# CameraHalDispatcher Mojo proxy. Camera clients can then ask
# CameraHalDispatcher Mojo proxy to get the handle to connect to the camera HAL
# adapter.
pre-start script
# If the usbcam-device-added event is triggered too early, the environment
# such as the /run/camera directory might not be ready yet. Ignore the usbcam
# event in that case and wait "starting system-services" event to start
# cros-camera again when the environment is ready.
if [ "${UPSTART_EVENTS}" = "usbcam-device-added" ] && \
! status system-services | grep -q "start/running"; then
logger -t cros-camera "system-services hasn't started yet, ignore."
stop
exit 0
fi
# Run the board-specific setup hooks, if any.
sh /etc/camera/setup-hooks.sh || true
[ -e "${UVC_HWTIMESTAMPS_FILE}" ] && echo 1 > "${UVC_HWTIMESTAMPS_FILE}" || true
if [ "$(cros_config /camera clock)" = "boottime" ]; then
printf "boottime" > "${UVC_CLOCK_FILE}" || true
fi
# Ensure that the server token directory exists so that it can be bind-mounted
# into the minijail that cros-camera runs in.
sudo -u chronos -g arc-camera mkdir -m 770 -p -- "${SERVER_TOKEN_DIR}"
end script
post-start script
# Run the board-specific hooks, if any.
sh /etc/camera/post-start-hooks.sh || true
end script
post-stop script
goal=$(status cros-camera | awk '{split($2, a, "/"); print a[1]}')
if [ "${goal}" = "start" ]; then
# Sleep only if it's respawning, so we don't need to wait when doing `stop
# cros-camera` in tests or manually.
sleep "${RESPAWN_DELAY}"
fi
end script
# Need -G to be in video group to access /dev/video*.
# Need access to original network namespace for udev (no -e), which passes
# uevents via netlink socket.
# Need access to /proc, /sys, /dev to perform USB enumeration.
# Need access to /var/cache/camera to read camera parameters.
# Need access to /var/lib/timezone to read correct timezone.
# Need access to /run/systemd/journal for logging (crbug.com/932761)
# Need read access to /run/chromeos-config/v1 for access to chromeos-config.
# Need (writable) access to /dev/shm to share memory with Android.
# Need (writable) access to /sys/kernel/debug/tracing to log events.
# Need (writable) access to /var/lib/metrics to log metrics.
# Need (writable) access to /run/dbus for DBus communications.
# Set RLIMIT_NICE(=13) to 40,40
exec minijail0 -i -u arc-camera -g arc-camera -G \
-N -p -r -l -t \
-v -P /mnt/empty -b / -b /proc -b /sys -b /dev \
-k 'tmpfs,/var,tmpfs,MS_NOSUID|MS_NODEV|MS_NOEXEC' -b /var/cache/camera \
-b /var/lib/timezone -b /dev/shm,,1 -b /sys/kernel/debug \
-b /sys/kernel/debug/tracing,,1 \
-k 'tmpfs,/run,tmpfs,MS_NOSUID|MS_NODEV|MS_NOEXEC' \
-b /run/camera,,1 -b "${SERVER_TOKEN_DIR}" -b /run/systemd/journal \
-b /run/udev/data -b /run/chromeos-config/v1 \
-b /var/lib/metrics,,1 -b /run/dbus/ \
-R 13,40,40 \
-n -S "${SECCOMP_POLICY_FILE}" \
-- /usr/bin/cros_camera_service