Android培訓班(38) – Android移動開發技術文章_手機開發 Android移動開發教學課程

<!– @page { margin: 2cm } P { margin-bottom: 0.21cm } –>


在init.rc文件裡,可以看到加載下面的服務:


service dbus /system/bin/dbus-daemon –system –nofork


socket dbus stream 660 bluetooth bluetooth


user bluetooth


group bluetooth net_bt_admin


dbus服務的代碼在目錄:


Android-2.0/external/dbus/bus


dbus服務是android使用的一種特殊的進程間通訊系統。它具有面向對象接口的協議,以及應用程序之間互相發現和監視的守護進程。dbus設計用來作為用戶與系統服務之間的分隔以及系統服務之間的通訊。因此,dbus通訊安全,但效率有點差。


它的主要入口函數代碼如下:


int


main (int argc, char **argv)


{


DBusError error;


DBusString config_file;


DBusString addr_fd;


DBusString pid_fd;


const char *prev_arg;


int print_addr_fd;


int print_pid_fd;


int i;


dbus_bool_t print_address;


dbus_bool_t print_pid;


int force_fork;


 


初始化配置文件/文件句柄/進程ID。


if (!_dbus_string_init (&config_file))


return 1;


 


if (!_dbus_string_init (&addr_fd))


return 1;


 


if (!_dbus_string_init (&pid_fd))


return 1;


 


print_address = FALSE;


print_pid = FALSE;


force_fork = FORK_FOLLOW_CONFIG_FILE;


 


 


下面分析進程輸入的參數。


prev_arg = NULL;


i = 1;


while (i < argc)


{


const char *arg = argv[i];


 


if (strcmp (arg, “–help”) == 0 ||


strcmp (arg, “-h”) == 0 ||


strcmp (arg, “-?”) == 0)


usage ();


else if (strcmp (arg, “–version”) == 0)


version ();


else if (strcmp (arg, “–introspect”) == 0)


introspect ();


else if (strcmp (arg, “–nofork”) == 0)


force_fork = FORK_NEVER;


else if (strcmp (arg, “–fork”) == 0)


force_fork = FORK_ALWAYS;


else if (strcmp (arg, “–system”) == 0)


{


check_two_config_files (&config_file, “system”);


 


if (!_dbus_string_append (&config_file, DBUS_SYSTEM_CONFIG_FILE))


exit (1);


}


else if (strcmp (arg, “–session”) == 0)


{


check_two_config_files (&config_file, “session”);


 


if (!_dbus_string_append (&config_file, DBUS_SESSION_CONFIG_FILE))


exit (1);


}


else if (strstr (arg, “–config-file=”) == arg)


{


const char *file;


 


check_two_config_files (&config_file, “config-file”);


 


file = strchr (arg, =);


++file;


 


if (!_dbus_string_append (&config_file, file))


exit (1);


}


else if (prev_arg &&


strcmp (prev_arg, “–config-file”) == 0)


{


check_two_config_files (&config_file, “config-file”);


 


if (!_dbus_string_append (&config_file, arg))


exit (1);


}


else if (strcmp (arg, “–config-file”) == 0)


; /* wait for next arg */


else if (strstr (arg, “–print-address=”) == arg)


{


const char *desc;


 


check_two_addr_descriptors (&addr_fd, “print-address”);


 


desc = strchr (arg, =);


++desc;


 


if (!_dbus_string_append (&addr_fd, desc))


exit (1);


 


print_address = TRUE;


}


else if (prev_arg &&


strcmp (prev_arg, “–print-address”) == 0)


{


check_two_addr_descriptors (&addr_fd, “print-address”);


 


if (!_dbus_string_append (&addr_fd, arg))


exit (1);


 


print_address = TRUE;


}


else if (strcmp (arg, “–print-address”) == 0)


print_address = TRUE; /* and well get the next arg if appropriate */


else if (strstr (arg, “–print-pid=”) == arg)


{


const char *desc;


 


check_two_pid_descriptors (&pid_fd, “print-pid”);


 


desc = strchr (arg, =);


++desc;


 


if (!_dbus_string_append (&pid_fd, desc))


exit (1);


 


print_pid = TRUE;


}


else if (prev_arg &&


strcmp (prev_arg, “–print-pid”) == 0)


{


check_two_pid_descriptors (&pid_fd, “print-pid”);


 


if (!_dbus_string_append (&pid_fd, arg))


exit (1);


 


print_pid = TRUE;


}


else if (strcmp (arg, “–print-pid”) == 0)


print_pid = TRUE; /* and well get the next arg if appropriate */


else


usage ();


 


prev_arg = arg;


 


++i;


}


 


根據輸入的參數進行初始化總線。


if (_dbus_string_get_length (&config_file) == 0)


{


fprintf (stderr, “No configuration file specified.
“);


usage ();


}


 


print_addr_fd = -1;


if (print_address)


{


print_addr_fd = 1; /* stdout */


if (_dbus_string_get_length (&addr_fd) > 0)


{


long val;


int end;


if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) ||


end != _dbus_string_get_length (&addr_fd) ||


val < 0 || val > _DBUS_INT_MAX)


{


fprintf (stderr, “Invalid file descriptor: “%s”
“,


_dbus_string_get_const_data (&addr_fd));


exit (1);


}


 


print_addr_fd = val;


}


}


_dbus_string_free (&addr_fd);


 


print_pid_fd = -1;


if (print_pid)


{


print_pid_fd = 1; /* stdout */


if (_dbus_string_get_length (&pid_fd) > 0)


{


long val;


int end;


if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) ||


end != _dbus_string_get_length (&pid_fd) ||


val < 0 || val > _DBUS_INT_MAX)


{


fprintf (stderr, “Invalid file descriptor: “%s”
“,


_dbus_string_get_const_data (&pid_fd));


exit (1);


}


 


print_pid_fd = val;


}


}


_dbus_string_free (&pid_fd);


 


if (!bus_selinux_pre_init ())


{


_dbus_warn (“SELinux pre-initialization failed
“);


exit (1);


}


 


dbus_error_init (&error);


 


註冊監視進程的服務函數。


context = bus_context_new (&config_file, force_fork,


print_addr_fd, print_pid_fd,


&error);


_dbus_string_free (&config_file);


if (context == NULL)


{


_dbus_warn (“Failed to start message bus: %s
“,


error.message);


dbus_error_free (&error);


exit (1);


}


 


setup_reload_pipe (bus_context_get_loop (context));


 


_dbus_set_signal_handler (SIGHUP, signal_handler);


_dbus_set_signal_handler (SIGTERM, signal_handler);


#ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX


_dbus_set_signal_handler (SIGIO, signal_handler);


#endif /* DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX */


 


_dbus_verbose (“We are on D-Bus…
“);


 


進入服務循環。


_dbus_loop_run (bus_context_get_loop (context));


 


bus_context_shutdown (context);


bus_context_unref (context);


bus_selinux_shutdown ();


 


return 0;


}

發佈留言