#!/usr/bin/env vpython3
#
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Helps launch lacros-chrome with mojo connection established on Linux
  or Chrome OS. Use on Chrome OS is for dev purposes.

  The main use case is to be able to launch lacros-chrome in a debugger.

  Please first launch an ash-chrome in the background as usual except without
  the '--lacros-chrome-path' argument and with an additional
  '--lacros-mojo-socket-for-testing' argument pointing to a socket path:

  XDG_RUNTIME_DIR=/tmp/ash_chrome_xdg_runtime ./out/ash/chrome \\
      --user-data-dir=/tmp/ash-chrome --enable-wayland-server \\
      --no-startup-window --enable-features=LacrosSupport \\
      --lacros-mojo-socket-for-testing=/tmp/lacros.sock

  Then, run this script with '-s' pointing to the same socket path used to
  launch ash-chrome, followed by a command one would use to launch lacros-chrome
  inside a debugger:

  EGL_PLATFORM=surfaceless XDG_RUNTIME_DIR=/tmp/ash_chrome_xdg_runtime \\
  ./build/lacros/mojo_connection_lacros_launcher.py -s /tmp/lacros.sock
  gdb --args ./out/lacros-release/chrome --user-data-dir=/tmp/lacros-chrome
"""

import argparse
import array
import contextlib
import getpass
import grp
import os
import pathlib
import pwd
import resource
import socket
import sys
import subprocess


_NUM_FDS_MAX = 3


# contextlib.nullcontext is introduced in 3.7, while Python version on
# CrOS is still 3.6. This is for backward compatibility.
class NullContext:
  def __init__(self, enter_ret=None):
    self.enter_ret = enter_ret

  def __enter__(self):
    return self.enter_ret

  def __exit__(self, exc_type, exc_value, trace):
    pass


def _ReceiveFDs(sock):
  """Receives FDs from ash-chrome that will be used to launch lacros-chrome.

    Args:
      sock: A connected unix domain socket.

    Returns:
      File objects for the mojo connection and maybe startup data file.
    """
  # This function is borrowed from with modifications:
  # https://docs.python.org/3/library/socket.html#socket.socket.recvmsg
  fds = array.array("i")  # Array of ints
  # Along with the file descriptor, ash-chrome also sends the version in the
  # regular data.
  version, ancdata, _, _ = sock.recvmsg(
      1, socket.CMSG_LEN(fds.itemsize * _NUM_FDS_MAX))
  for cmsg_level, cmsg_type, cmsg_data in ancdata:
    if cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS:
      # There are three versions currently this script supports.
      # The oldest one: ash-chrome returns one FD, the mojo connection of
      # old bootstrap procedure (i.e., it will be BrowserService).
      # The middle one: ash-chrome returns two FDs, the mojo connection of
      # old bootstrap procedure, and the second for the start up data FD.
      # The newest one: ash-chrome returns three FDs, the mojo connection of
      # old bootstrap procedure, the second for the start up data FD, and
      # the third for another mojo connection of new bootstrap procedure.
      # TODO(crbug.com/1156033): Clean up the code to drop the support of
      # oldest one after M91.
      # TODO(crbug.com/1180712): Clean up the mojo procedure support of the
      # the middle one after M92.
      cmsg_len_candidates = [(i + 1) * fds.itemsize
                             for i in range(_NUM_FDS_MAX)]
      assert len(cmsg_data) in cmsg_len_candidates, (
          'CMSG_LEN is unexpected: %d' % (len(cmsg_data), ))
      fds.frombytes(cmsg_data[:])

  if version == b'\x01':
    assert len(fds) == 2, 'Expecting exactly 2 FDs'
    startup_fd = os.fdopen(fds[0])
    mojo_fd = os.fdopen(fds[1])
  elif version:
    raise AssertionError('Unknown version: \\x%s' % version.hex())
  else:
    raise AssertionError('Failed to receive startup message from ash-chrome. '
                         'Make sure you\'re logged in to Chrome OS.')
  return startup_fd, mojo_fd


def _MaybeClosing(fileobj):
  """Returns closing context manager, if given fileobj is not None.

    If the given fileobj is none, return nullcontext.
    """
  return (contextlib.closing if fileobj else NullContext)(fileobj)


def _ApplyCgroups():
  """Applies cgroups used in ChromeOS to lacros chrome as well."""
  # Cgroup directories taken from ChromeOS session_manager job configuration.
  UI_FREEZER_CGROUP_DIR = '/sys/fs/cgroup/freezer/ui'
  UI_CPU_CGROUP_DIR = '/sys/fs/cgroup/cpu/ui'
  pid = os.getpid()
  with open(os.path.join(UI_CPU_CGROUP_DIR, 'tasks'), 'a') as f:
    f.write(str(pid) + '\n')
  with open(os.path.join(UI_FREEZER_CGROUP_DIR, 'cgroup.procs'), 'a') as f:
    f.write(str(pid) + '\n')


def _PreExec(uid, gid, groups):
  """Set environment up for running the chrome binary."""
  # Nice and realtime priority values taken ChromeOSs session_manager job
  # configuration.
  resource.setrlimit(resource.RLIMIT_NICE, (40, 40))
  resource.setrlimit(resource.RLIMIT_RTPRIO, (10, 10))
  os.setgroups(groups)
  os.setgid(gid)
  os.setuid(uid)


def Main():
  arg_parser = argparse.ArgumentParser()
  arg_parser.usage = __doc__
  arg_parser.add_argument(
      '-r',
      '--root-env-setup',
      action='store_true',
      help='Set typical cgroups and environment for chrome. '
      'If this is set, this script must be run as root.')
  arg_parser.add_argument(
      '-s',
      '--socket-path',
      type=pathlib.Path,
      required=True,
      help='Absolute path to the socket that were used to start ash-chrome, '
      'for example: "/tmp/lacros.socket"')
  flags, args = arg_parser.parse_known_args()

  assert 'XDG_RUNTIME_DIR' in os.environ
  assert os.environ.get('EGL_PLATFORM') == 'surfaceless'

  if flags.root_env_setup:
    # Check if we are actually root and error otherwise.
    assert getpass.getuser() == 'root', \
        'Root required environment flag specified, but user is not root.'
    # Apply necessary cgroups to our own process, so they will be inherited by
    # lacros chrome.
    _ApplyCgroups()
  else:
    print('WARNING: Running chrome without appropriate environment. '
          'This may affect performance test results. '
          'Set -r and run as root to avoid this.')

  with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
    sock.connect(flags.socket_path.as_posix())
    startup_connection, mojo_connection = (_ReceiveFDs(sock))

  with _MaybeClosing(startup_connection), _MaybeClosing(mojo_connection):
    cmd = args[:]
    pass_fds = []
    if startup_connection:
      cmd.append('--cros-startup-data-fd=%d' % startup_connection.fileno())
      pass_fds.append(startup_connection.fileno())
    if mojo_connection:
      cmd.append('--crosapi-mojo-platform-channel-handle=%d' %
                 mojo_connection.fileno())
      pass_fds.append(mojo_connection.fileno())

    env = os.environ.copy()
    if flags.root_env_setup:
      username = 'chronos'
      p = pwd.getpwnam(username)
      uid = p.pw_uid
      gid = p.pw_gid
      groups = [g.gr_gid for g in grp.getgrall() if username in g.gr_mem]
      env['HOME'] = p.pw_dir
      env['LOGNAME'] = username
      env['USER'] = username

      def fn():
        return _PreExec(uid, gid, groups)
    else:

      def fn():
        return None

    proc = subprocess.Popen(cmd, pass_fds=pass_fds, preexec_fn=fn)

  return proc.wait()


if __name__ == '__main__':
  sys.exit(Main())
