code: def _exec_cmd(self, args, shell, timeout, stderr):
          
          if timeout and timeout <= 0:
              raise ValueError('Timeout is not a positive value: %s' % timeout)
          try:
              (ret, out, err) = utils.run_command(
                  args, shell=shell, timeout=timeout)
          except psutil.TimeoutExpired:
              raise AdbTimeoutError(
                  cmd=args, timeout=timeout, serial=self.serial)
  
          if stderr:
              stderr.write(err)
          logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
                        utils.cli_cmd_to_string(args), out, err, ret)
          if ret == 0:
              return out
          else:
              raise AdbError(
                  cmd=args,
                  stdout=out,
                  stderr=err,
                  ret_code=ret,
                  serial=self.serial)
docs: Executes adb commands.
  
          Args:
              args: string or list of strings, program arguments.
                  See subprocess.Popen() documentation.
              shell: bool, True to run this command through the system shell,
                  False to invoke it directly. See subprocess.Popen() docs.
              timeout: float, the number of seconds to wait before timing out.
                  If not specified, no timeout takes effect.
              stderr: a Byte stream, like io.BytesIO, stderr of the command will
                  be written to this object if provided.
  
          Returns:
              The output of the adb command run if exit code is 0.
  
          Raises:
              ValueError: timeout value is invalid.
              AdbError: The adb command exit code is not 0.
              AdbTimeoutError: The adb command timed out.