gsi_util: try to use executable in local bin/ folder

cmd_utils.run_command() will try to find the executable file
in the local bin/ folder firstly.

The patch also add some missing dependency files and make sure
gsi_util could run alone.

Bug: 75992357
Test: ./run_test.py
Test: './build.py setup_env',
  then './gsi_util.bin check_compat --system adb --vendor adb' in
  another terminal without lunch

Change-Id: I923eb68b4a6829c8ed5e5d8278e97fd4f5860efc
diff --git a/gsi/gsi_util/Android.bp b/gsi/gsi_util/Android.bp
index d1b1131..abc08f5 100644
--- a/gsi/gsi_util/Android.bp
+++ b/gsi/gsi_util/Android.bp
@@ -28,6 +28,7 @@
     "adb",
     "avbtool",
     "checkvintf",
+    "secilc",
     "simg2img",
   ],
   version: {
diff --git a/gsi/gsi_util/build.py b/gsi/gsi_util/build.py
index c8e09c7..a5ec304 100755
--- a/gsi/gsi_util/build.py
+++ b/gsi/gsi_util/build.py
@@ -37,6 +37,8 @@
     RequiredItem('bin/checkvintf', 'bin/checkvintf'),
     RequiredItem('lib64/libbase.so', 'lib64/libbase.so'),
     RequiredItem('lib64/liblog.so', 'lib64/liblog.so'),
+    RequiredItem('bin/secilc', 'bin/secilc'),
+    RequiredItem('lib64/libsepol.so', 'lib64/libsepol.so'),
     RequiredItem('bin/simg2img', 'bin/simg2img'),
     RequiredItem('lib64/libc++.so', 'lib64/libc++.so'),
 ]  # pyformat: disable
diff --git a/gsi/gsi_util/gsi_util/utils/cmd_utils.py b/gsi/gsi_util/gsi_util/utils/cmd_utils.py
index 7fc1181..4493b5c 100644
--- a/gsi/gsi_util/gsi_util/utils/cmd_utils.py
+++ b/gsi/gsi_util/gsi_util/utils/cmd_utils.py
@@ -17,18 +17,37 @@
 from collections import namedtuple
 import logging
 import os
+import shlex
 import subprocess
+import sys
 
 
 CommandResult = namedtuple('CommandResult', 'returncode stdoutdata, stderrdata')
 PIPE = subprocess.PIPE
 
+_LOCAL_BIN_PATH = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),
+                               'bin')
+
+
+def _update_command_for_local(command, kwargs):
+  if kwargs.get('shell', False):
+    # do nothing for shell commands
+    return
+
+  prog = command[0]
+  local_prog = os.path.join(_LOCAL_BIN_PATH, prog)
+  if os.path.isfile(local_prog) and os.access(local_prog, os.X_OK):
+    logging.debug('Using local executable: %s', local_prog)
+    command[0] = local_prog
+
 
 def run_command(command, read_stdout=False, read_stderr=False,
                 log_stdout=False, log_stderr=False,
                 raise_on_error=True, sudo=False, **kwargs):
   """Runs a command and returns the results.
 
+    The method tries to use the executable in bin/ firstly.
+
   Args:
     command: A sequence of command arguments or else a single string.
     read_stdout: If True, includes stdout data in the returned tuple.
@@ -50,6 +69,8 @@
     OSError: Not such a command to execute, raised by subprocess.Popen().
     subprocess.CalledProcessError: The return code of the command is nonzero.
   """
+  _update_command_for_local(command, kwargs)
+
   if sudo and os.getuid() != 0:
     if kwargs.pop('shell', False):
       command = ['sudo', 'sh', '-c', command]