亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > C++ > 正文

詳細(xì)分析Android中實(shí)現(xiàn)Zygote的源碼

2020-05-23 14:16:48
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

這篇文章主要介紹了詳細(xì)分析Android中實(shí)現(xiàn)Zygote的源碼,包括底層的C/C++代碼以及Java代碼部分入口,需要的朋友可以參考下

概述

在Android系統(tǒng)中,所有的應(yīng)用程序進(jìn)程,以及用來(lái)運(yùn)行系統(tǒng)關(guān)鍵服務(wù)的System進(jìn)程都是由zygote進(jìn)程負(fù)責(zé)創(chuàng)建的。因此,我們將它稱(chēng)為進(jìn)程孵化器。zygote進(jìn)程是通過(guò)復(fù)制自身的方式來(lái)創(chuàng)建System進(jìn)程和應(yīng)用程序進(jìn)程的。由于zygote進(jìn)程在啟動(dòng)時(shí)會(huì)在內(nèi)部創(chuàng)建一個(gè)虛擬機(jī)實(shí)例,因此,通過(guò)復(fù)制zygote進(jìn)程而得到的System進(jìn)程和應(yīng)用程序進(jìn)程可以快速地在內(nèi)部獲得一個(gè)虛擬機(jī)實(shí)例拷貝。

zygote進(jìn)程在啟動(dòng)完成之后,會(huì)馬上將System進(jìn)程啟動(dòng)起來(lái),以便它可以將系統(tǒng)的關(guān)鍵服務(wù)啟動(dòng)起來(lái)。下面我們將介紹zygote進(jìn)程的啟動(dòng)腳本,然后分析它和System進(jìn)程的啟動(dòng)過(guò)程。

zygote分析

zygote進(jìn)程的啟動(dòng)腳本如下:

 

 
  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
  2. class main 
  3. socket zygote stream 660 root system 
  4. onrestart write /sys/android_power/request_state wake 
  5. onrestart write /sys/power/state on 
  6. onrestart restart media 
  7. onrestart restart netd 

解析配置文件

在我之前的一篇博客中已經(jīng)分析了init進(jìn)程是如何啟動(dòng)service服務(wù)了,需要了解的同學(xué)可以參考這篇文章:Android init進(jìn)程——

通過(guò)zygote服務(wù)的啟動(dòng)腳本,我們可以知道,zygote進(jìn)程的實(shí)際是二進(jìn)制文件app_process的調(diào)用,我們就從這個(gè)應(yīng)用程序的main函數(shù)入手去分析一下zygote進(jìn)程的啟動(dòng)過(guò)程,源碼如下(/frameworks/base/cmds/app_process/app_main.cpp):

 

 
  1. /** 
  2. * 將-Xzygote加入到JavaVMOption中,返回/system/bin參數(shù)指向的下標(biāo) 
  3. */ 
  4. int AndroidRuntime::addVmArguments(int argc, const charconst argv[]) 
  5. int i; 
  6.  
  7. for (i = 0; i < argc; i ++) { 
  8. if (argv[i][0] != '-') { 
  9. return i; 
  10. if (argv[i][1] == '-' && argv[i][2] == 0) { 
  11. return i + 1; 
  12.  
  13. JavaVMOption opt; 
  14. memset(&opt, 0, sizeof(opt)); 
  15. opt.optionString = (char*)argv[i]; 
  16. mOptions.add(opt); 
  17. return i; 
  18.  
  19. int main(int argc, charconst argv[]) 
  20. // zygote call parameters 
  21. // /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
  22.  
  23. // These are global variables in ProcessState.cpp 
  24. mArgC = argc; 
  25. mArgV = argv; 
  26.  
  27. mArgLen = 0; 
  28. for (int i = 0; i < argc; i ++) { 
  29. mArgLen += strlen(argv[i]) + 1; 
  30. // 去除末尾的空格 
  31. mArgLen--; 
  32.  
  33. AppRuntime runtime; 
  34. const char* argv0 = argv[0]; 
  35.  
  36. // Process command line arguments 
  37. // ignore argv[0] 
  38. argc --; 
  39. argv ++; 
  40.  
  41. // Everything up tp '--' or first non '-' arg goes to the vm 
  42. int i = runtime.addVmArguments(argc, argv); 
  43.  
  44. // Parse runtime arguments. Stop at first unrecognized option. 
  45. bool zygote = false
  46. bool startSystemServer = false
  47. bool application = false
  48. const char* parentDir = NULL; 
  49. const char* niceName = NULL; 
  50. const char* className = NULL; 
  51. while (i < argc) { 
  52. const char* arg = argv[i ++]; 
  53. if (!parentDir) { 
  54. parentDir = arg; 
  55. else if (strcmp(arg, "--zygote") == 0) { 
  56. zygote = true
  57. niceName = "zygote"
  58. else if (strcmp(arg, "--start-system-server") == 0) { 
  59. startSystemServer = true
  60. else if (strcmp(arg, "--application") == 0) { 
  61. application = true
  62. else if (strncmp(arg, "--nice-name=", 12)) { 
  63. niceName = arg + 12; 
  64. else { 
  65. className = arg; 
  66. break
  67.  
  68. if (niceName && *niceName) { 
  69. setArgv0(argv0, niceName); 
  70. set_process_name(niceName); 
  71.  
  72. runtime.mParentDir = parentDir; 
  73.  
  74. if (zygote) { 
  75. // 進(jìn)入到AppRuntime的start函數(shù) 
  76. runtime.start("com.android.internal.os.ZygoteInit"
  77. startSystemServer? "start-system-server" : ""); 
  78. else if (className) { 
  79. runtime.mClassName = className; 
  80. runtime.mArgc = argc - i; 
  81. runtime.mArgv = argv + i; 
  82. runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool"); 
  83. else { 
  84. fprintf("stderr""Error: no class name or --zygote supplied./n"); 
  85. app_usage(); 
  86. LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied"); 
  87. return 10; 

在zygote的main函數(shù)中,通過(guò)AppRuntime runtime代碼創(chuàng)建了一個(gè)AppRuntime對(duì)象runtime,接下來(lái)Zygote進(jìn)程就是通過(guò)它來(lái)進(jìn)一步啟動(dòng)的。

init.rc中關(guān)于啟動(dòng)zygote命令中包含了–zygote參數(shù),所以在if(strcmp(arg, “–zygote”) == 0)判斷的時(shí)候,會(huì)將niceName賦值為”zygote”,然后通過(guò)set_process_name(niceName)函數(shù)將當(dāng)前進(jìn)程的名稱(chēng)設(shè)置為zygote。這也是為什么調(diào)用的腳本為/system/bin/app_process,而進(jìn)程名為zygote的原因。set_process_name函數(shù)的源碼如下(/system/core/libcutils/process_name.c):

 

 
  1. static const char* process_name = "unknown"
  2. void set_process_name(const char* new_name) 
  3. if (new_name == NULL) { 
  4. return
  5.  
  6. int len = strlen(new_name); 
  7. char* copy = (char*)malloc(len + 1); 
  8. strcpy(copy, new_name); 
  9. process_name = (const char*) copy; 

從init.rc文件中關(guān)于zygote進(jìn)程的配置參數(shù)可知,Zygote進(jìn)程傳遞給應(yīng)用程序app_process的啟動(dòng)參數(shù)arg還包含一個(gè)”–start-system-server”選項(xiàng)。因此,在調(diào)用AppRuntime對(duì)象runtime的成員函數(shù)start時(shí),第二個(gè)參數(shù)為”start-system-server”,表示zygote進(jìn)程啟動(dòng)完成之后,需要將system進(jìn)程啟動(dòng)起來(lái)。

AppRuntime分析

AppRuntime類(lèi)的成員函數(shù)start是從父類(lèi)AndroidRuntime繼承下來(lái)的,因此,接下來(lái)我們就繼續(xù)分析AndroidRuntime類(lèi)的成員函數(shù)start的實(shí)現(xiàn),函數(shù)源碼位置:/frameworks/base/core/jni/AndroidRuntime.cpp:

 

 
  1. char* AndroidRuntime::toSlashClassName(const char* className) 
  2. char* result = strdup(className); 
  3. for (char* cp = result; *cp != '/0'; cp ++) { 
  4. if (*cp == '.') { 
  5. *cp = '/'
  6.  
  7. return result; 
  8.  
  9. /** 
  10. * Start the Android runtime. This involves starting the virtual machine 
  11. * and calling the "static void main(String[] args)" method int the class 
  12. * named by "className". 
  13. * 
  14. * 這兩個(gè)參數(shù)的值分別為: 
  15. * const char* className = "com.android.internal.os.ZygoteInit"; 
  16. * const char* options = "start-system-server"; 
  17. */ 
  18. void AndroidRuntime::start(const char* className, const char* options) 
  19. ALOGD("/n>>>>> AndroidRuntime START %s <<<<<</n"
  20. className != NULL ? className : "(unknown)"); 
  21.  
  22. /** 
  23. * 'startSystemServer == true' means runtime is obsolete and not run from 
  24. * init.rc anymore, so we print out the boot start event here. 
  25. */ 
  26. if (strcmp(options, "start-system-server") == 0) { 
  27. const int LOG_BOOT_PROGRESS_START = 3000; 
  28. LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); 
  29.  
  30. // 設(shè)置ANDROID_ROOT環(huán)境變量 
  31. const char* rootDir = getenv("ANDROID_ROOT"); 
  32. if (rootDir == NULL) { 
  33. rootDir = "/system"
  34. if (!hasDir("/system")) { 
  35. LOG_FATAL("No root directory specified, and /android dose not exist."); 
  36. return
  37. setenv("ANDROID_ROOT", rootDir, 1); 
  38.  
  39.  
  40. JniInvocation jni_invocation; 
  41. jni_invocation.Init(NULL); 
  42. JNIEnv* env; 
  43. // 1. 創(chuàng)建虛擬機(jī) 
  44. if (startVm(&mJavaVM, &env) != 0) { 
  45. return
  46. onVmCreated(env); 
  47.  
  48. // 2. 注冊(cè)JNI函數(shù) 
  49. if (startReg(env) < 0) { 
  50. ALOGE("Unable to register all android natives/n"); 
  51. return
  52.  
  53. jclass stringClass; 
  54. jobjectArray strArray; 
  55. jstring classNameStr; 
  56. jstring optionsStr; 
  57.  
  58. stringClass = env->FindClass("java/lang/String"); 
  59. assert(stringClass != NULL); 
  60. // 創(chuàng)建一個(gè)有兩個(gè)元素的String數(shù)組,用Java代碼表示為:String[] strArray = new String[2]; 
  61. strArray = env->NewObjectArray(2, stringClass, NULL); 
  62. assert(strArray != NULL); 
  63. classNameStr = env->NewStringUTF(className); 
  64. assert(classNameStr != NULL); 
  65. // 設(shè)置第一個(gè)元素為"com.android.internal.os.ZygoteInit" 
  66. env->SetObjectArrayElement(strArray, 0, classNameStr); 
  67. optionsStr = env->NewStringUTF(options); 
  68. // 設(shè)置第二個(gè)元素為"start-system-server" 
  69. env->SetObjectArrayElement(strArray, 1, optionsStr); 
  70.  
  71. // 將字符串"com.android.internal.os.ZygoteInit"轉(zhuǎn)換為"com/android/internal/os/ZygoteInit" 
  72. char* slashClassName = toSlashClassName(className); 
  73. jclass startClass = env->FindClass(slashClassName); 
  74. if (startClass == NULL) { 
  75. ALOGE("JavaVM unable to locate class '%s'/n", slashClassName); 
  76. else { 
  77. jmethodID startMeth = env->GetStaticMethodID(startClass, "main""([Ljava/lang/String;)V"); 
  78. if (startMeth == NULL) { 
  79. ALOGE("JavaVM unable to find main() in '%s/n'", className); 
  80. else { 
  81. // 3. 
  82. // 通過(guò)JNI調(diào)用java函數(shù),注意調(diào)用的是main函數(shù),所屬的類(lèi)是"com.android.internal.os.ZygoteInit". 
  83. // 傳遞的參數(shù)是"com.android.internal.os.ZygoteInit true" 
  84. env->CallStaticVoidMethod(startClass, startMeth, strArray); 
  85. free(slashClassName); 
  86.  
  87. ALOGD("Shutting down VM/n"); 
  88. if (mJavaVM->DetachCurrentThread() != JNI_OK) { 
  89. ALOGW("Warning: unable to detach main thread/n"); 
  90. if (mJavaVM->DestoryJavaVM() != 0) { 
  91. ALOGW("Warning: VM did not shut down cleanly/n"); 

上述代碼有幾處關(guān)鍵點(diǎn),分別是:

創(chuàng)建虛擬機(jī)。

注冊(cè)JNI函數(shù)。

進(jìn)入Java世界。

接下來(lái),我們分別分析這三個(gè)關(guān)鍵點(diǎn)。

創(chuàng)建虛擬機(jī)——startVm

startVm并沒(méi)有特別之處,就是調(diào)用JNI的虛擬機(jī)創(chuàng)建函數(shù),但是創(chuàng)建虛擬機(jī)時(shí)的一些參數(shù)卻是在startVm中確定的,其源碼如下:

 

 
  1. #define PROPERTY_VALUE_MAX 92 
  2. /** 
  3. * Start the Dalvik Virtual Machine. 
  4. * 
  5. * Various arguments, most determined by system properties, are passed in. 
  6. * The "mOptions" vector is updated. 
  7. * 
  8. * Returns 0 on success. 
  9. */ 
  10. int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIENV** pEnv) 
  11. int result = -1; 
  12. JavaVMInitArgs initArgs; 
  13. JavaVMOption opt; 
  14. char propBuf[PROPERTY_VALUE_MAX]; 
  15. char stackTraceFileBuf[PROPERTY_VALUE_MAX]; 
  16. char dexoptFlagsBuf[PROPERTY_VALUE_MAX]; 
  17. char enableAssertBuf[sizeof("-ea:")-1 + PROPERTY_VALUE_MAX]; 
  18. char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX]; 
  19. char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; 
  20. char heapsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX]; 
  21. char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX]; 
  22. char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX]; 
  23. char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX]; 
  24. char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX]; 
  25. char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX]; 
  26. char extraOptsBuf[PROPERTY_VALUE_MAX]; 
  27. char* stackTraceFile = NULL; 
  28. bool checkJni = false
  29. bool checkDexSum = false
  30. bool logStdio = false
  31. enum { 
  32. KEMDefault, 
  33. KEMIntPortable, 
  34. KEMIntFast, 
  35. KEMJitCompiler, 
  36. } executionMode = KEMDefault; 
  37.  
  38. /** 
  39. * 這段代碼是用了設(shè)置JNI_check選項(xiàng)的。JNI_check指的是Native層調(diào)用JNI函數(shù)時(shí),系統(tǒng)所做的一些檢查動(dòng)作。 
  40. * 這個(gè)選項(xiàng)雖然能增加可靠性,但是還有一些副作用: 
  41. * 1. 因?yàn)闄z查工作比較耗時(shí),所以會(huì)影響系統(tǒng)運(yùn)行速度。 
  42. * 2. 有些檢查工作比較耗時(shí),一旦出錯(cuò),整個(gè)進(jìn)程會(huì)abort。 
  43. * 所以,JNI_check選項(xiàng)一般只在eng版本設(shè)置。 
  44. */ 
  45. property_get("dalvik.vm.checkjni", propBuf, ""); 
  46. if (strcmp(propBuf, "true") == 0) { 
  47. checkJni = true
  48. else if (strcmp(propBuf, "false") != 0) { 
  49. property_get("ro.kernel.android.checkjni", propBuf, ""); 
  50. if (propBuf[0] == '1') { 
  51. checkJni = true
  52.  
  53. property_get("dalvik.vm.execution-mode", propBuf, ""); 
  54. if (strcmp(propBuf, "int:portable") == 0) { 
  55. executionMode = KEMIntPortable; 
  56. else if (strcmp(propBuf, "int:fast") == 0) { 
  57. executionMode = KEMIntFast;  
  58. else if (strcmp(propBuf, "int:jit") == 0) { 
  59. executionMode = KEMJitCompiler; 
  60.  
  61. // ... 省略大部分參數(shù)設(shè)置 
  62.  
  63. /** 
  64. * 設(shè)置虛擬機(jī)的heapsize,默認(rèn)為16m。絕大多數(shù)廠商都會(huì)在build.prop文件里修改這個(gè)屬性,一般是256m。 
  65. * heapsize不能設(shè)置得過(guò)小,否則在操作大尺寸的圖片時(shí)無(wú)法分配所需的內(nèi)存。 
  66. */ 
  67. strcpy(heapsizeOptsBuf, "-Xmx"); 
  68. property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m"); 
  69. opt.optionString = heapsizeOptsBuf; 
  70. mOptions.add(opt); 
  71.  
  72. // ...... 
  73.  
  74. if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { 
  75. ALOGE("JNI_CreateJavaVM failed/n"); 
  76. goto bail; 
  77.  
  78. result = 0; 
  79.  
  80. bail: 
  81. free(stackTraceFile); 
  82. return result; 

更多虛擬機(jī)參數(shù)的設(shè)置,我這里就不做特殊說(shuō)明了,大家感興趣可以自行g(shù)oogle。(ps:因?yàn)槲也惶摂M機(jī)這一塊…)

注冊(cè)JNI函數(shù)——startReg

上面講了如何創(chuàng)建虛擬機(jī),接下來(lái)需要給這個(gè)虛擬機(jī)注冊(cè)一些JNI函數(shù)。正是因?yàn)楹罄m(xù)的Java世界用到的一些函數(shù)是采用native方式實(shí)現(xiàn)的,所以才必須提前注冊(cè)這些函數(shù)。

接下來(lái),我們來(lái)看一下startReg函數(shù)的源碼實(shí)現(xiàn):

 

 
  1. int AndroidRuntime::startReg(JNIEnv* env) 
  2. // 設(shè)置Thread類(lèi)的線程創(chuàng)建函數(shù)為javaCreateThreadEtc 
  3. androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc); 
  4.  
  5. ALOGV("--- registering native functions ---/n"); 
  6.  
  7. env->PushLocalFrame(200); 
  8.  
  9. if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { 
  10. env->PopLocalFrame(NULL); 
  11. return -1; 
  12. env->PopLocalFrame(NULL); 
  13.  
  14. return 0; 

關(guān)鍵是需要注冊(cè)JNI函數(shù),具體實(shí)現(xiàn)是由register_jni_procs函數(shù)實(shí)現(xiàn)的,我們來(lái)看一下這個(gè)函數(shù)的具體實(shí)現(xiàn)(/frameworks/base/core/jni/AndroidRuntime.cpp):

 

 
  1. static int register_jni_procs(const RegJNIRec array[], size_T count, JNIEnv* env) 
  2. for (size_t i = 0; i < count; i ++) { 
  3. if (array[i].mProc(env) < 0) { 
  4. #ifndef NDEBUG 
  5. ALOGD("------!!! %s failed to load/n", array[i].mName); 
  6. #endif 
  7. return -1; 
  8.  
  9. return 0; 

通過(guò)源碼,我們可以看到,register_jni_procs只是對(duì)array數(shù)組的mProc函數(shù)的封裝,而array數(shù)組指向的是gRegJNI數(shù)組,我們來(lái)看一下這個(gè)數(shù)組的實(shí)現(xiàn):

 

 
  1. static const RegJNIRec gRegJNI[] = { 
  2. REG_JNI(register_android_debug_JNITest), 
  3. REG_JNI(register_com_android_internal_os_RuntimeInit), 
  4. REG_JNI(register_android_os_SystemClock), 
  5. REG_JNI(register_android_util_EventLog), 
  6. REG_JNI(register_android_util_Log), 
  7. REG_JNI(register_android_util_FloatMath), 
  8. REG_JNI(register_android_text_format_Time), 
  9. REG_JNI(register_android_content_AssetManager), 
  10. REG_JNI(register_android_content_StringBlock), 
  11. REG_JNI(register_android_content_XmlBlock), 
  12. REG_JNI(register_android_emoji_EmojiFactory), 
  13. REG_JNI(register_android_text_AndroidCharacter), 
  14. REG_JNI(register_android_text_AndroidBidi), 
  15. REG_JNI(register_android_view_InputDevice), 
  16. REG_JNI(register_android_view_KeyCharacterMap), 
  17. REG_JNI(register_android_os_Process), 
  18. REG_JNI(register_android_os_SystemProperties), 
  19. REG_JNI(register_android_os_Binder), 
  20. REG_JNI(register_android_os_Parcel), 
  21. REG_JNI(register_android_view_DisplayEventReceiver), 
  22. REG_JNI(register_android_nio_utils), 
  23. REG_JNI(register_android_graphics_Graphics), 
  24. REG_JNI(register_android_view_GraphicBuffer), 
  25. REG_JNI(register_android_view_GLES20DisplayList), 
  26. REG_JNI(register_android_view_GLES20Canvas), 
  27. REG_JNI(register_android_view_HardwareRenderer), 
  28. REG_JNI(register_android_view_Surface), 
  29. REG_JNI(register_android_view_SurfaceControl), 
  30. REG_JNI(register_android_view_SurfaceSession), 
  31. REG_JNI(register_android_view_TextureView), 
  32. REG_JNI(register_com_google_android_gles_jni_EGLImpl), 
  33. REG_JNI(register_com_google_android_gles_jni_GLImpl), 
  34. REG_JNI(register_android_opengl_jni_EGL14), 
  35. REG_JNI(register_android_opengl_jni_EGLExt), 
  36. REG_JNI(register_android_opengl_jni_GLES10), 
  37. REG_JNI(register_android_opengl_jni_GLES10Ext), 
  38. REG_JNI(register_android_opengl_jni_GLES11), 
  39. REG_JNI(register_android_opengl_jni_GLES11Ext), 
  40. REG_JNI(register_android_opengl_jni_GLES20), 
  41. REG_JNI(register_android_opengl_jni_GLES30), 
  42.  
  43. REG_JNI(register_android_graphics_Bitmap), 
  44. REG_JNI(register_android_graphics_BitmapFactory), 
  45. REG_JNI(register_android_graphics_BitmapRegionDecoder), 
  46. REG_JNI(register_android_graphics_Camera), 
  47. REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), 
  48. REG_JNI(register_android_graphics_Canvas), 
  49. REG_JNI(register_android_graphics_ColorFilter), 
  50. REG_JNI(register_android_graphics_DrawFilter), 
  51. REG_JNI(register_android_graphics_Interpolator), 
  52. REG_JNI(register_android_graphics_LayerRasterizer), 
  53. REG_JNI(register_android_graphics_MaskFilter), 
  54. REG_JNI(register_android_graphics_Matrix), 
  55. REG_JNI(register_android_graphics_Movie), 
  56. REG_JNI(register_android_graphics_NinePatch), 
  57. REG_JNI(register_android_graphics_Paint), 
  58. REG_JNI(register_android_graphics_Path), 
  59. REG_JNI(register_android_graphics_PathMeasure), 
  60. REG_JNI(register_android_graphics_PathEffect), 
  61. REG_JNI(register_android_graphics_Picture), 
  62. REG_JNI(register_android_graphics_PorterDuff), 
  63. REG_JNI(register_android_graphics_Rasterizer), 
  64. REG_JNI(register_android_graphics_Region), 
  65. REG_JNI(register_android_graphics_Shader), 
  66. REG_JNI(register_android_graphics_SurfaceTexture), 
  67. REG_JNI(register_android_graphics_Typeface), 
  68. REG_JNI(register_android_graphics_Xfermode), 
  69. REG_JNI(register_android_graphics_YuvImage), 
  70. REG_JNI(register_android_graphics_pdf_PdfDocument), 
  71.  
  72. REG_JNI(register_android_database_CursorWindow), 
  73. REG_JNI(register_android_database_SQLiteConnection), 
  74. REG_JNI(register_android_database_SQLiteGlobal), 
  75. REG_JNI(register_android_database_SQLiteDebug), 
  76. REG_JNI(register_android_os_Debug), 
  77. REG_JNI(register_android_os_FileObserver), 
  78. REG_JNI(register_android_os_MessageQueue), 
  79. REG_JNI(register_android_os_SELinux), 
  80. REG_JNI(register_android_os_Trace), 
  81. REG_JNI(register_android_os_UEventObserver), 
  82. REG_JNI(register_android_net_LocalSocketImpl), 
  83. REG_JNI(register_android_net_NetworkUtils), 
  84. REG_JNI(register_android_net_TrafficStats), 
  85. REG_JNI(register_android_net_wifi_WifiNative), 
  86. REG_JNI(register_android_os_MemoryFile), 
  87. REG_JNI(register_com_android_internal_os_ZygoteInit), 
  88. REG_JNI(register_android_hardware_Camera), 
  89. REG_JNI(register_android_hardware_camera2_CameraMetadata), 
  90. REG_JNI(register_android_hardware_SensorManager), 
  91. REG_JNI(register_android_hardware_SerialPort), 
  92. REG_JNI(register_android_hardware_UsbDevice), 
  93. REG_JNI(register_android_hardware_UsbDeviceConnection), 
  94. REG_JNI(register_android_hardware_UsbRequest), 
  95. REG_JNI(register_android_media_AudioRecord), 
  96. REG_JNI(register_android_media_AudioSystem), 
  97. REG_JNI(register_android_media_AudioTrack), 
  98. REG_JNI(register_android_media_JetPlayer), 
  99. REG_JNI(register_android_media_RemoteDisplay), 
  100. REG_JNI(register_android_media_ToneGenerator), 
  101.  
  102. REG_JNI(register_android_opengl_classes), 
  103. REG_JNI(register_android_server_NetworkManagementSocketTagger), 
  104. REG_JNI(register_android_server_Watchdog), 
  105. REG_JNI(register_android_ddm_DdmHandleNativeHeap), 
  106. REG_JNI(register_android_backup_BackupDataInput), 
  107. REG_JNI(register_android_backup_BackupDataOutput), 
  108. REG_JNI(register_android_backup_FileBackupHelperBase), 
  109. REG_JNI(register_android_backup_BackupHelperDispatcher), 
  110. REG_JNI(register_android_app_backup_FullBackup), 
  111. REG_JNI(register_android_app_ActivityThread), 
  112. REG_JNI(register_android_app_NativeActivity), 
  113. REG_JNI(register_android_view_InputChannel), 
  114. REG_JNI(register_android_view_InputEventReceiver), 
  115. REG_JNI(register_android_view_InputEventSender), 
  116. REG_JNI(register_android_view_InputQueue), 
  117. REG_JNI(register_android_view_KeyEvent), 
  118. REG_JNI(register_android_view_MotionEvent), 
  119. REG_JNI(register_android_view_PointerIcon), 
  120. REG_JNI(register_android_view_VelocityTracker), 
  121.  
  122. REG_JNI(register_android_content_res_ObbScanner), 
  123. REG_JNI(register_android_content_res_Configuration), 
  124.  
  125. REG_JNI(register_android_animation_PropertyValuesHolder), 
  126. REG_JNI(register_com_android_internal_content_NativeLibraryHelper), 
  127. REG_JNI(register_com_android_internal_net_NetworkStatsFactory), 
  128. }; 
  129.  
  130. #ifdef NDEBUG 
  131. #define REG_JNI(name) {name} 
  132. struct RegJNIRec { 
  133. int (*mProc)(JNIEnv*); 
  134. }; 
  135. #else 
  136. #define REG_JNI(name) {name, #name} 
  137. struct RegJNIRec { 
  138. int (*mProc)(JNIEnv*); 
  139. const char* mName; 
  140. }; 
  141. #endif 

可以看到,REG_JNI是一個(gè)宏,宏里面包括的就是那個(gè)參數(shù)為JNIEnv*,返回值為int的函數(shù)指針mProc,我們以register_android_debug_JNITest為例,源碼位置為/frameworks/base/core/jni/android_debug_JNITest.cpp:

 

 
  1. #define NELEM(x) (sizeof(x)/sizeof(*(x))) 
  2.  
  3. int register_android_debug_JNITest(JNIEnv* env) 
  4. return jniRegisterNativeMethods(env, "android/debug/JNITest", gMethods, NELEM(gMethods)); 

可以看到,mProc其實(shí)就是為Java類(lèi)注冊(cè)JNI函數(shù)。

進(jìn)入JAVA世界

可以看到CallStaticVoidMethod最終將調(diào)用com.android.internal.os.ZygoteInit的main函數(shù),下面就來(lái)看一下這個(gè)Java世界的入口函數(shù)。源碼位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,源碼如下:

 

 
  1. public static void main(String argv[]) 
  2. try { 
  3. SamplingProfilerIntegration.start(); 
  4.  
  5. // 1. 注冊(cè)zygote用的socket 
  6. registerZygoteSocket(); 
  7. EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); 
  8.  
  9. // 2. 預(yù)加載類(lèi)和資源 
  10. preload(); 
  11. EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); 
  12.  
  13. SamplingProfilerIntegration.writeZygoteSnapshot(); 
  14.  
  15. // 強(qiáng)制執(zhí)行一次垃圾收集 
  16. gc(); 
  17.  
  18. Trace.setTracingEnabled(false); 
  19.  
  20. if (argv.length != 2) { 
  21. throw new RuntimeException(argv[0] + USAGE_STRING); 
  22.  
  23. if (argv[1].equals("start-system-server")) { 
  24. // 3. 啟動(dòng)system-server 
  25. startSystemServer(); 
  26. else if (!argv[1].equals("")) { 
  27. throw new RuntimeException(argv[0] + USAGE_STRING); 
  28.  
  29. Log.i(TAG, "Accepting command socket connections"); 
  30.  
  31. // 4. 進(jìn)入請(qǐng)求應(yīng)答模式 
  32. runSelectLoop(); 
  33. closeServerSocket(); 
  34.  
  35. catch(MethodAndArgsCaller caller) { 
  36. caller.run(); 
  37. catch(RuntimeException ex) { 
  38. Log.e(TAG, "Zygote died with exception", ex); 
  39. closeServerSocket(); 
  40. throw ex; 

上述代碼中有5個(gè)重要的點(diǎn),我已經(jīng)通過(guò)標(biāo)號(hào)標(biāo)記出來(lái)了,接下來(lái)我們分別分析一下這5點(diǎn)函數(shù)的具體實(shí)現(xiàn)。

建立IPC通信服務(wù)端——registerZygoteSocket

zygote及系統(tǒng)中其他程序的通信沒(méi)有使用Binder,而是采用了基于AF_UNIX類(lèi)型的socket。registerZygoteSocket函數(shù)的使命正是建立這個(gè)Socket,實(shí)現(xiàn)代碼如下:

 

 
  1. private static void registerZygoteSocket() 
  2. if (sServerSocket == null) { 
  3. int fileDesc; 
  4. try { 
  5. String env = System.getenv(ANDROID_SOCKET_ENV); 
  6. fileDesc = Integer.parseInt(env); 
  7. catch (RuntimeException ex) { 
  8. throw new RuntimeException(ANDROID_SOCKET_ENV + " unset or invalid", ex); 
  9.  
  10. try {  
  11. sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc)); 
  12. catch(IOException ex) {  
  13. throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex); 
  14.  
  15. public class LocalServerSocket { 
  16. private final LocalSocketImpl impl; 
  17. private final LocalSocketAddress localAddress; 
  18.  
  19. private static final int LISTEN_BACKLOG = 50; 
  20.  
  21. /** 
  22. * Create a LocalServerSocket from a file descriptor that's already 
  23. * been created and bound. listen() will be called immediately on it. 
  24. * Used for cases where file descriptors are passed in via environment 
  25. * variables. 
  26. */ 
  27. public LocalServerSocket(FileDescriptor fd) throws IOException { 
  28. impl = new LocalSocketImpl(fd); 
  29. impl.listen(LISTEN_BACKLOG); 
  30. localAddress = impl.getSockAddress(); 

registerZygoteSocket很簡(jiǎn)單,就是創(chuàng)建一個(gè)服務(wù)端的socket。

預(yù)加載類(lèi)和資源——preload

我們先來(lái)看一下preload函數(shù)實(shí)現(xiàn):

 

 
  1. static void preload() 
  2. preloadClasses(); 
  3. preloadResources(); 
  4. preloadOpenGL(); 

preload函數(shù)里面分別調(diào)用了三個(gè)預(yù)加載函數(shù),我們分別來(lái)分析一下這幾個(gè)函數(shù)的實(shí)現(xiàn)。

首先是preloadClasses,函數(shù)實(shí)現(xiàn)如下:

 

 
  1. private static final int UNPRIVILEGED_UID = 9999; 
  2. private static final int UNPRIVILEGED_GID = 9999; 
  3.  
  4. private static final int ROOT_UID = 0; 
  5. private static final int ROOT_GID = 0; 
  6.  
  7. private static void preloadClasses() 
  8. final VMRuntime runtime = VMRuntime.getRuntime(); 
  9.  
  10. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(PRELOADED_CLASSES); 
  11. if (is == null) { 
  12. Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + "."); 
  13. else { 
  14. Log.i(TAG, "Preloading classes..."); 
  15. long startTime = SystemClock.uptimeMillis(); 
  16.  
  17. setEffectiveGroup(UNPRIVILEGED_GID); 
  18. setEffectiveGroup(UNPRIVILEGED_UID); 
  19.  
  20. float defaultUtilization = runtime.getTargetHeapUtilization(); 
  21. runtime.setTargetHeapUtilization(0.8f); 
  22.  
  23. System.gc(); 
  24. runtime.runFinalizationSync(); 
  25. Debug.startAllocCounting(); 
  26.  
  27. try { 
  28. // 創(chuàng)建一個(gè)緩沖區(qū)為256字符的輸入流 
  29. BufferedReader br = new BufferdReader(new InputStreamReader(is), 256); 
  30. int count = 0; 
  31. String line; 
  32. while ((line = br.readLine()) != null) { 
  33. // skip comments and blank lines. 
  34. line = line.trim(); 
  35. if (line.startsWith("#") || line.equals("")) { 
  36. continue
  37.  
  38. try { 
  39. if (false) { 
  40. Log.v(TAG, "Preloading " + line + "..."); 
  41. Class.forName(line); 
  42. count ++; 
  43. catch (ClassNotFoundException e) { 
  44. Log.w(TAG, "Class not found for preloading: " + line); 
  45. catch (UnsatisfiedLinkError e) { 
  46. Log.w(TAG, "Problem preloading " + line + ": " + e); 
  47. catch(Throwable t) { 
  48. Log.e(TAG, "Error preloading " + line + ".", t); 
  49. Log.i(TAG, "...preloaded " + count + " classes in " + (SystemClock.uptimeMillis()-startTime) + "ms."); 
  50. catch (IOException e) { 
  51. Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e); 
  52. finally { 
  53. IoUtils.closeQuietly(is); 
  54. runtime.setTargetHeapUtilization(defaultUtilization); 
  55.  
  56. runtime.preloadDexCaches(); 
  57. Debug.stopAllocCounting(); 
  58.  
  59. setEffectiveUser(ROOT_UID); 
  60. setEffectiveGroup(ROOT_GID); 

preloadClasses看起來(lái)很簡(jiǎn)單,但是實(shí)際上它有很多的類(lèi)需要加載。可以查看一下/frameworks/base/preloaded-classes文件,這里面都是需要預(yù)加載的類(lèi)。

接下來(lái),分析一下preloadResources函數(shù)的源碼:

 

 
  1. private static final boolean PRELOAD_RESOURCES = true
  2. private static void preloadResources() 
  3. final VMRuntime runtime = VMRuntime.getRuntime(); 
  4. Debug.startAllocCounting(); 
  5.  
  6. try { 
  7. System.gc(); 
  8. runtime.runFinalizationSync(); 
  9. mResources = Resources.getSystem(); 
  10. mResources.startPreloading(); 
  11. if (PRELOAD_RESOURCES) { 
  12. Log.i(TAG, "Preloading resources..."); 
  13.  
  14. long startTime = SystemClock.uptimeMillis(); 
  15. TypedArray ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_drawables); 
  16. int N = preloadDrawables(runtime, ar); 
  17. ar.recycle(); 
  18. Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis()-startTime) + "ms."); 
  19.  
  20. startTime = SystemClock.uptimeMillis(); 
  21. ar = mResources.obtainTypedArray(com.android.internal.R.array.preloaded_color_state_lists); 
  22. N = preloadColorstateLists(runtime, ar); 
  23. ar.recycle(); 
  24. Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); 
  25. mResources.finishPreloading(); 
  26. catch (RuntimeException e) { 
  27. Log.w(TAG, "Failure preloading resources", e); 
  28. finally { 
  29. Debug.stopAllocCounting(); 

接下來(lái),是預(yù)加載OpenGL。源碼如下:

 

 
  1. private static void preloadOpenGL() 
  2. if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) { 
  3. EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 

啟動(dòng)system_server

現(xiàn)在我們要分析第三個(gè)關(guān)鍵點(diǎn):startSystemServer。這個(gè)函數(shù)會(huì)創(chuàng)建java世界中系統(tǒng)Service所駐留的進(jìn)程system_server,該進(jìn)程是framework的核心。如何system_server掛掉,會(huì)導(dǎo)致zygote自殺。我們來(lái)看一下startSystemServer()實(shí)現(xiàn)源碼。

  1. /** 
  2. * Prepare the arguments and fork for the system server process. 
  3. */ 
  4. private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException 
  5. long capabilities = posixCapabilitiesAsBits( 
  6. OsConstants.CAP_KILL, 
  7. OsConstants.CAP_NET_ADMIN, 
  8. OsConstants.CAP_NET_BIND_SERVICE, 
  9. OsConstants.CAP_NET_BROADCAST, 
  10. OsConstants.CAP_NET_RAW, 
  11. OsConstants.CAP_SYS_MODULE, 
  12. OsConstants.CAP_SYS_NICE, 
  13. OsConstants.CAP_SYS_RESOURCE, 
  14. OsConstants.CAP_SYS_TIME, 
  15. OsConstants.CAP_SYS_TTY_CONFIG 
  16. ); 
  17.  
  18. // 設(shè)置參數(shù) 
  19. String args[] = { 
  20. "--setuid=1000"
  21. "--setgid=1000"
  22. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007"
  23. "--capabilities=" + capabilities + "," + capabilities, 
  24. "--runtime-init"
  25. "--nice-name=system_server"// 進(jìn)程名為system_server 
  26. "com.android.server.SystemServer"
  27. }; 
  28.  
  29. ZygoteConnection.Arguments parsedArgs = null
  30.  
  31. int pid; 
  32.  
  33. try { 
  34. parsedArgs = new ZygoteConnection.Arguments(args); 
  35. ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); 
  36. ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 
  37.  
  38. /* Request to fork the system server process */ 
  39. pid = Zygote.forkSystemServer( 
  40. parsedArgs.uid, parsedArgs.gid, 
  41. parsedArgs.gids, 
  42. parsedArgs.debugFlags, 
  43. null
  44. parsedArgs.permittedCapabilities, 
  45. parsedArgs.effectiveCapabilities 
  46. ); 
  47. catch (IllegalArgumentException ex) { 
  48. throw new RuntimeException(ex); 
  49.  
  50. /* For child process */ 
  51. if (pid == 0) { 
  52. handleSystemServerProcess(parsedArgs); 
  53.  
  54. return true

 

有求必應(yīng)之等待請(qǐng)求——runSelectLoop

zygote從startSystemServer返回后,將進(jìn)入第四個(gè)關(guān)鍵的函數(shù):runSelectLoop。我們來(lái)看一下這個(gè)函數(shù)的實(shí)現(xiàn):

 

 
  1. static final int GC_LOOP_COUNT = 10; 
  2. private static void runSelectLoop() throws MethodAndArgsCaller { 
  3. ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); 
  4. ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); 
  5. FileDescriptor[] fdArray = new FileDescriptor[4]; 
  6.  
  7. fds.add(sServerSocket.getFileDescriptor()); 
  8. peers.add(null); 
  9.  
  10. int loopCount = GC_LOOP_COUNT; 
  11. while (true) { 
  12. int index; 
  13. if (loopCount <= 0) { 
  14. gc(); 
  15. loopCount = GC_LOOP_COUNT; 
  16. else { 
  17. loopCount --; 
  18.  
  19. try { 
  20. fdArray = fds.toArray(fdArray); 
  21. index = selectReadable(fdArray); 
  22. catch(IOException ex) { 
  23. throw new RuntimeException("Error in select()", ex); 
  24.  
  25. if (index < 0) { 
  26. throw new RuntimeException("Error in select()"); 
  27. else if (index == 0) { 
  28. ZygoteConnection newPeer = acceptCommandPeer(); 
  29. peers.add(newPeer); 

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
国精品人妻无码一区二区三区喝尿| 人妻大战黑人白浆狂泄| 欧美在线不卡| 欧美精品成人一区二区在线观看| 草莓视频一区二区三区| 日本h片在线观看| 免费一级黄色大片| 波多野结衣电车痴汉| 在线一区二区三区视频| 嫩草影院发布页| 国产成人精品1024| 亚洲欧洲视频在线观看| 亚洲欧美一区二区在线观看| 精品国产乱码久久久久久浪潮| 午夜美女福利视频| 久久伊伊香蕉| 欧美日韩精品久久久| 欧美一区在线看| 色av性av丰满av| 性xxxx18| 91麻豆精品国产无毒不卡在线观看| 91久久香蕉国产日韩欧美9色| 欧美一卡2卡三卡4卡5免费| 国产精品va无码一区二区| 91美女在线免费观看| 亚洲高清不卡在线| 国产一级黄色片免费| 久久久亚洲一区| 黄色小视频在线看| 国产亚洲欧美一区二区三区| 国内在线精品| 红桃视频 国产| 久热中文在线| 国产欧美三级| 亚洲亚裔videos黑人hd| 国产欧美精品一区二区三区四区| 精品日本一区二区三区| 清纯唯美一区二区三区| www亚洲国产| 夜夜揉揉日日人人青青一国产精品| gogogo高清在线观看一区二区| 成人黄色免费网站在线观看| 欧洲美女7788成人免费视频| 天堂在线免费av| 欧美成人精品欧美一级| 久久久久88色偷偷免费| 国产一级又黄| 日本xxxxxx| 亚洲精品免费在线观看视频| 国产免费一区二区三区四区| ckplayer中文字幕| 国产精品自产拍在线观看2019| 久久久精品蜜桃| 蜜桃狠狠色伊人亚洲综合网站| 久久99青青| 欧美另类z0zx974| 精品影院一区| 中文字幕亚洲精品在线观看| 色偷偷偷在线视频播放| 91视频导航| 狠狠色2019综合网| 亚洲精品久久久久久久久久久| 中文字幕在线观看免费高清| 在线日韩av永久免费观看| 日本视频在线观看| 欧美日韩免费电影| 亚洲欧美精品午睡沙发| 亚洲人成电影在线播放| 国产亚洲精品久久久久久牛牛| 色噜噜狠狠成人网p站| 久久国产精品免费一区| 日本jizzcom| 91麻豆精品国产综合久久久久久| 91视频在线观看免费| 国产丝袜在线播放| 日本电影全部在线观看网站视频| 天堂俺去俺来也www久久婷婷| 无码人妻aⅴ一区二区三区69岛| 国产精品1区2区3区在线观看| 99色精品视频| 性欧美18一19性猛交| 日韩欧美有码在线| xxxx69视频| 久久天堂精品| 日本亚洲欧美在线| 免费av网站在线播放| av网站在线观看免费| 最新中文字幕日本| 亚洲五月激情网| 超级碰碰不卡在线视频| 成人精品福利| 亚洲自拍另类综合| 91丝袜美腿高跟国产极品老师| 911久久香蕉国产线看观看| 午夜久久中文| 欧美日韩国产一二三区| 欧美老熟妇乱大交xxxxx| 卡一精品卡二卡三网站乱码| 欧美成人精品影院| 亚洲女人18毛片水真多| 极品美女一区二区三区| 国产999精品久久久| 成人性生交大片免费观看网站| 精品视频在线播放一区二区三区| 首播影院在线观看免费观看电视| 激情小说亚洲色图| 天天av综合| av资源在线播放| 亚洲一区精品在线| 中文字幕一区不卡| 欧美精品久久99久久在免费线| 欧美国产成人精品一区二区三区| 日韩在线视频免费观看| 任我爽在线视频| 久久久精品三级| 国产一区二区三区免费在线观看| 91久久精品午夜一区二区| 欧美在线亚洲一区| 大乳在线免费观看| 欧洲精品久久久| www.久久com| 国产九色91回来了| av片在线免费观看| 久久久午夜精品理论片中文字幕| 欧美jizz18| 91精品蜜臀一区二区三区在线| 亚洲激情在线播放| 在线免费观看一区二区| 国产人妖乱国产精品人妖| 成人免费淫片aa视频免费| 四虎4545www国产精品| 天天色综合久久| www.av导航| 北条麻妃视频在线| 国产精品草草| 欧美一级片在线免费观看| 日韩欧美激情视频| 成人小视频免费观看| 中文字幕在线不卡| 丰满少妇又爽又紧又丰满电影| 69国产精品视频免费观看| 无码毛片aaa在线| 久热综合在线亚洲精品| 青青草国产免费一区二区下载| 成人欧美一区二区三区在线| 国产清纯白嫩初高生在线观看91| 日本久久一级片| 波多野结衣之无限发射| 成人激情黄色网| 热re99久久精品国产99热| 国产视频一区二区视频| 天天操天天摸天天舔| 国产亚洲欧美另类一区二区三区| 羞羞网站在线看| 国产成人精品一区二区三区视频| 精品黑人一区二区三区国语馆| 亚洲精品一区二三区不卡| 成人au免费视频影院| 欧美精品在线网站| 精品一区二区三区四区五区六区| 日本性爱视频在线观看| 日韩欧美三级在线| 美女被c网站| 色愁久久久久久| 91青青草视频| 日本在线观看视频一区| 美日韩精品视频免费看| 一级爱爱免费视频| 国产网红主播福利一区二区| 中日精品一色哟哟| yw193.com尤物在线| 亚洲三级网址| 亚洲第一综合天堂另类专| 日本欧美黄色| 成人片黄网站色大片免费毛片| 资源网第一页久久久| 精品区在线观看| 亚洲男同性恋视频| 中文字幕中文字幕在线中心一区| 精品欧美一区二区三区精品久久| 成人免费高清| 欧美激情综合五月色丁香| 精品无码久久久久成人漫画| 欧美乱大交xxxxxbbb| 亚洲成在人线免费| 国产成人综合一区| 国产精品无码久久av| 亚洲欧美精品在线| 久久久久久久久丰满| 欧美三级美国一级| 黄色片网站免费在线观看| 亚欧激情乱码久久久久久久久| 色哟哟一区二区在线观看| 亚洲欧美国产一区二区三区| 91在线观看入口| 欧美亚洲激情在线| www视频在线播放| 欧美亚洲国产另类| 国产xxxxxx久色视频在| 冲田杏梨av在线| 欧美一区=区三区| 在线视频一区二区| 亚洲伊人观看| 成人黄色免费网址| 欧美综合在线观看| 中文文精品字幕一区二区| 亚洲免费网站观看视频| 国产视频在线看| 亚在线播放中文视频| 四虎影成人精品a片| 老司机性视频| 日韩电影在线看| 牛牛精品成人免费视频| 日韩一区二区精品视频| 欧美日本韩国一区二区三区视频| 成人做爰69片免费| 最新97超碰在线| 又紧又大又爽精品一区二区| 免费成人美女在线观看| 特级丰满少妇一级| 99re热这里只有精品视频| 久久精视频免费在线久久完整在线看| 在线观看国产一级片| 国产精品一区二三区| 国产色婷婷国产综合在线理论片a| 青青九九免费视频在线| 免费一级肉体全黄毛片| 正在播放91九色| 欧美人与禽猛交乱配| 国产精品一区二区在线观看网站| 欧美日韩伦理在线免费| www男人天堂| 亚洲午夜视频在线观看| 先锋影音欧美性受| 欧美性受xxxx黒人xyx性爽| 另类专区欧美蜜桃臀第一页| 免费看成人午夜电影| 色爱综合网欧美| 97人人爽人人爽人人爽| 欧美精品第三页| 天堂а在线中文在线无限看推荐| 色八戒一区二区三区| 四虎久久影院| 在线黄色免费网站| 日韩欧美a级片| 欧美一区二区三区视频免费播放| 久久久精品人妻一区二区三区四| 老司机精品久久| 欧美黄色免费网站| 91国偷自产一区二区三区成为亚洲经典| 日本一区二区成人| 欧美激情综合色综合啪啪| 欧美午夜精品久久久久久人妖| 三级小说欧洲区亚洲区| 中文字幕有码视频| 日韩欧美在线第一页| 美女精品网站| 成人久久久久久久| 久久99精品国产麻豆婷婷洗澡| 久久电影视频| 免费在线观看视频一区| 国产精品免费久久久久影院| 国产精品久久不卡| 99国产精品久久一区二区三区| 欧美一级二级在线观看| 四虎电影院在线观看| 一本色道久久加勒比精品| 国内自拍九色| 五月婷婷之综合激情| 国产精品亚洲综合在线观看| 成人性色av| 日韩中文字幕欧美| 99久久国产综合精品女小说| av资源网在线观看| 国产欧美不卡| 欧美精品日韩一本| 成人精品一区二区三区电影黑人| 四虎影院在线播放| 欧美freesex8一10精品| 北条麻妃一区二区三区在线| 91九色蝌蚪视频| 老牛影视免费一区二区| 九九热精品在线播放| 日本猛少妇色xxxxx免费网站| 久久精品一级片| 亚洲av成人无码网天堂| 中文字幕日韩av电影| 日韩三级网址| 国产精品香蕉国产| 久久久久久久久福利| 久久精品一区二区三区四区五区| 香蕉视频官网在线观看日本一区二区| 国产人久久人人人人爽| 免费看av的网址| 午夜精品一区二区在线观看| 欧美绝品在线观看成人午夜影视| 懂色av中文字幕| 日本成人黄色片| 99久久99久久精品国产片果冻| 欧美日本高清视频| 杨幂一区二区三区免费看视频| 91日本韩国| 久久久精品久久久久| 欧美日韩第一页| 精品国产人成亚洲区| 国产亚洲欧美精品久久久www| 九九九伊在线综合永久| 免费日韩一区二区三区| 99成人在线| 欧美家庭影院| 91麻豆精品国产91久久久久久| 免费观看在线色综合| 亚洲欧美国产精品久久久久久久| 亚洲国产精品黑人久久久| 亚洲人精品午夜射精日韩| 国产小视频福利在线| 久久亚洲精品一区二区| 日本免费一区二区三区四区| 亚洲精品一区二区毛豆| 精品亚洲视频在线| 一二三区中文字幕| 自拍偷拍国产亚洲| 高h视频在线播放| 国产精品久久久久久久精| 久久久久久五月天久久久久久久久| 99精品国产在热久久下载| 中文在线中文字幕| 午夜精品美女自拍福到在线|