Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

【android x86 5.1.1】 adb install 流程分析

$
0
0

adb install 流程解析

相关文件及函数调用流程

adb install 流程

 

system/core/adb/adb.c àmain()

system/core/adb/commandline.c àadb_commandline()

system/core/adb/commandline.c àinstall_app()

system/core/adb/commandline.c àpm_command()

system/core/adb/commandline.c à send_shellcommand()

system/core/adb/Adb_client.c àadb_connect()

system/core/adb/Transport.c à writex()

system/core/adb/Sysdeps_win32.c à adb_write()

system/core/adb/Sysdeps_win32.c->fh_write()

system/core/adb/commandline.c àdo_cmd() à va_start()

 

 

 


 

1、 进入adb

代码位置:system/core/adb/adb.c àmain()

运行adb install命令之后,第一步是进入adbmain函数当中,此处我们的adb命令是从windows上发出的,所以是进入到ADB_HOST当中,所以将命令adb install *.apk去掉adb变成install *.apk传递到adb_commandline(int, char**)

int main(int argc, char **argv)

{

#if ADB_HOST

   adb_sysdeps_init();

   adb_trace_init();

   D("Handling commandline()\n");

   return adb_commandline(argc - 1, argv + 1);

#else

   /* If adbd runs inside the emulator this will enable adb tracing via

    * adb-debug qemud service in the emulator. */

   adb_qemu_trace_init();

   while(1) {

       int c;

       int option_index = 0;

       static struct option opts[] = {

           {"root_seclabel", required_argument, 0, 's' },

           {"device_banner", required_argument, 0, 'b' }

       };

       c = getopt_long(argc, argv, "", opts, &option_index);

       if (c == -1)

           break;

       switch (c) {

       case 's':

           root_seclabel = optarg;

           break;

       case 'b':

           adb_device_banner = optarg;

           break;

       default:

           break;

       }

    }

 

   start_device_log();

   D("Handling main()\n");

   return adb_main(0, DEFAULT_ADB_PORT);

#endif

}

 

2、 判断命令

函数位置system/core/adb/commandline.c àadb_commandline()

int adb_commandline(int argc, char **argv)

{

   

   /* modifiers and flags */

       //确定修饰与标志

   while(argc > 0) {

       

    }

 

   adb_set_transport(ttype, serial);

   adb_set_tcp_specifics(server_port);

 

   if (is_server) {

       if (no_daemon || is_daemon) {

           r = adb_main(is_daemon, server_port);

       } else {

           r = launch_server(server_port);

       }

       if(r) {

           fprintf(stderr,"* could not start server *\n");

       }

       return r;

    }

 

top:

   if(argc == 0) {

       return usage();

    }

 

   ...

       //跳转安装应用,ttype为传输模式、serial为序列号,argcargv继续传递install*.apk

   if (!strcmp(argv[0], "install")) {

       if (argc < 2) return usage();

       return install_app(ttype, serial, argc, argv);

    }

 

   ...

 

   usage();

   return 1;

}

 

 

3、 得到安装应用的命令,将应用文件从电脑移动到手机的data文件夹或者sd卡当中

函数位置system/core/adb/commandline.c à install_app()

 

int install_app(transport_type transport,char* serial, int argc, char** argv)

{

       //目标数据位置

   static const char *const DATA_DEST = "/data/local/tmp/%s";

   static const char *const SD_DEST = "/sdcard/tmp/%s";

   const char* where = DATA_DEST;

   int i;

   struct stat sb;

 

       //-s可以安装到sd卡当中

   for (i = 1; i < argc; i++) {

       if (!strcmp(argv[i], "-s")) {

           where = SD_DEST;

       }

    }

 

   // Find last APK argument.

   // All other arguments passed through verbatim.

       //从最后一个argv开始查找,直到找到一个apk为止

   int last_apk = -1;

   for (i = argc - 1; i >= 0; i--) {

       char* file = argv[i];

       char* dot = strrchr(file, '.');

       if (dot && !strcasecmp(dot, ".apk")) {

           if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {

                fprintf(stderr, "InvalidAPK file: %s\n", file);

                return -1;

           }

 

           last_apk = i;

           break;

       }

    }

 

   if (last_apk == -1) {

       fprintf(stderr, "Missing APK file\n");

       return -1;

    }

 

   char* apk_file = argv[last_apk];

   char apk_dest[PATH_MAX];

   snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));

       //首先把应用从原来的位置放到apk_dest上,apk_dest目录在/data/local/tmp/

   int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */);

   if (err) {

       goto cleanup_apk;

    }else {

       argv[last_apk] = apk_dest; /* destination name, not source location */

    }

       //通过pm执行安装应用的命令

   pm_command(transport, serial, argc, argv);

 

cleanup_apk:

   delete_file(transport, serial, apk_dest);

   return err;

}

 

4、通过pm命令安装应用

 

static int pm_command(transport_typetransport, char* serial,

                      int argc, char** argv)

{

   char buf[4096];

 

   snprintf(buf, sizeof(buf), "shell:pm");

 

while(argc--> 0) {

       //将一些分割符号替换为\\符号

       char *quoted = escape_arg(*argv++);

       strncat(buf, " ", sizeof(buf) - 1);

       strncat(buf, quoted, sizeof(buf) - 1);

       free(quoted);

    }

       //此处传入的buff经过处理后的值是shell:pm install *.apk

   send_shellcommand(transport, serial, buf);

   return 0;

}

 

5、 调用shell执行pm命令

system/core/adb/commandline.c àsend_shellcommand()

 

static int send_shellcommand(transport_typetransport, char* serial, char* buf)

{

   int fd, ret;

 

for(;;) {

       //每秒通过adb_connect传递命令

       fd = adb_connect(buf);

       if(fd >= 0)

           break;

       fprintf(stderr,"- waiting for device -\n");

       adb_sleep_ms(1000);

       do_cmd(transport, serial, "wait-for-device", 0);

    }

 

   read_and_dump(fd);

   ret = adb_close(fd);

   if (ret)

       perror("close");

 

   return ret;

}

 

6、校验Adb服务端的情况并保证通过adb客户端传递信息时服务端正常运行

 

system/core/adb/Adb_client.c àadb_connect()

 

int adb_connect(const char *service)

{

   // first query the adb server's version

       //首先查询adb服务的版本

   int fd = _adb_connect("host:version");

 

       //然后检验adb服务的状态是否异常

   ...

 

   // if the command is start-server, we are done.

   if (!strcmp(service, "host:start-server"))

       return 0;

 

       //验证完成之后通过_adb_connect()继续传递参数

   fd = _adb_connect(service);

   if(fd == -1) {

       D("_adb_connect error: %s\n", __adb_error);

    } else if(fd == -2) {

       fprintf(stderr,"** daemon still not running\n");

    }

   D("adb_connect: return fd %d\n", fd);

 

   return fd;

error:

   adb_close(fd);

   return -1;

}

 

7、连接到服务端并通过writex写入长度以及具体的客户端命令

int _adb_connect(const char *service)

{

   char tmp[5];

   int len;

   int fd;

 

   D("_adb_connect: %s\n", service);

   len = strlen(service);

   if((len < 1) || (len > 1024)) {

       strcpy(__adb_error, "service name too long");

       return -1;

    }

   snprintf(tmp, sizeof tmp, "%04x", len);

 

   if (__adb_server_name)

       fd = socket_network_client(__adb_server_name, __adb_server_port,SOCK_STREAM);

   else

       fd = socket_loopback_client(__adb_server_port, SOCK_STREAM);

 

   if(fd < 0) {

       strcpy(__adb_error, "cannot connect to daemon");

       return -2;

    }

 

   if (memcmp(service,"host",4) != 0 &&switch_socket_transport(fd)) {

       return -1;

    }

      

       //此处写入长度以及命令

   if(writex(fd, tmp, 4) || writex(fd, service, len)) {

       strcpy(__adb_error, "write failure during connection");

       adb_close(fd);

       return -1;

    }

 

   if(adb_status(fd)) {

       adb_close(fd);

       return -1;

    }

 

   D("_adb_connect: return fd %d\n", fd);

   return fd;

}

 

8、通过adb_write()写入

 

int writex(int fd, const void *ptr, size_tlen)

{

   char *p = (char*) ptr;

   int r;

 

#if ADB_TRACE

   D("writex: fd=%d len=%d: ", fd, (int)len);

   dump_hex( ptr, len );

#endif

   while(len > 0) {

       r = adb_write(fd, p, len);

       if(r > 0) {

           len -= r;

           p += r;

       } else {

           if (r < 0) {

                D("writex: fd=%d error %d:%s\n", fd, errno, strerror(errno));

                if (errno == EINTR)

                    continue;

                if (errno == EAGAIN) {

                    adb_sleep_ms(1); // justyield some cpu time

                    continue;

                }

           } else {

                D("writex: fd=%ddisconnected\n", fd);

           }

           return -1;

       }

    }

   return 0;

}

 

 

9、写入adb驱动,通过fh_writeshell命令

System/core/adb/System_win32.c

 

int adb_write(int  fd, constvoid*  buf, int  len)

{

   FH     f = _fh_from_int(fd);

 

   if (f == NULL) {

       return -1;

    }

 

   return f->clazz->_fh_write(f, buf, len);

}

作者:class_brick 发表于2017/6/25 17:37:45 原文链接
阅读:297 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>