<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 101,  comments - 29,  trackbacks - 0

            在Android系統中,所有的應用程序進程以及系統服務進程SystemServer都是由Zygote進程孕育(fork)出來的,這也許就是為什么要把它稱為Zygote(受精卵)的原因吧。由于Zygote進程在Android系統中有著如此重要的地位,本文將詳細分析它的啟動過程。

            在前面一篇文章Android應用程序進程啟動過程的源代碼分析中,我們看到了,當ActivityManagerService啟動一個應用程序的時候,就會通過Socket與Zygote進程進行通信,請求它fork一個子進程出來作為這個即將要啟動的應用程序的進程;在前面兩篇文章Android應用程序安裝過程源代碼分析Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析中,我們又看到了,系統中的兩個重要服務PackageManagerService和ActivityManagerService,都是由SystemServer進程來負責啟動的,而SystemServer進程本身是Zygote進程在啟動的過程中fork出來的。

            我們知道,Android系統是基于Linux內核的,而在Linux系統中,所有的進程都是init進程的子孫進程,也就是說,所有的進程都是直接或者間接地由init進程fork出來的。Zygote進程也不例外,它是在系統啟動的過程,由init進程創建的。在系統啟動腳本system/core/rootdir/init.rc文件中,我們可以看到啟動Zygote進程的腳本命令:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
        socket zygote stream 666
        onrestart write /sys/android_power/request_state wake
        onrestart write /sys/power/state on
        onrestart restart media
        onrestart restart netd
    
            前面的關鍵字service告訴init進程創建一個名為"zygote"的進程,這個zygote進程要執行的程序是/system/bin/app_process,后面是要傳給app_process的參數。

     

            接下來的socket關鍵字表示這個zygote進程需要一個名稱為"zygote"的socket資源,這樣,系統啟動后,我們就可以在/dev/socket目錄下看到有一個名為zygote的文件。這里定義的socket的類型為unix domain socket,它是用來作本地進程間通信用的,具體可以參考前面一篇文章Android學習啟動篇提到的一書《Linux內核源代碼情景分析》的第七章--基于socket的進程間通信。前面我們說到的ActivityManagerService就是通這個socket來和zygote進程通信請求fork一個應用程序進程的了。

            最后的一系列onrestart關鍵字表示這個zygote進程重啟時需要執行的命令。

            關于init.rc文件的更多信息,請參考system/core/init/readme.txt文件。

            了解了這個信息之后,我們就知道Zygote進程要執行的程序便是system/bin/app_process了,它的源代碼位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函數是main。在繼續分析Zygote進程啟動的過程之前,我們先來看看它的啟動序列圖:


            下面我們就詳細分析每一個步驟。

            Step 1. app_process.main

            這個函數定義在frameworks/base/cmds/app_process/app_main.cpp文件中:

    int main(int argc, const char* const argv[])
    {
    	// These are global variables in ProcessState.cpp
    	mArgC = argc;
    	mArgV = argv;
    
    	mArgLen = 0;
    	for (int i=0; i<argc; i++) {
    		mArgLen += strlen(argv[i]) + 1;
    	}
    	mArgLen--;
    
    	AppRuntime runtime;
    	const char *arg;
    	argv0 = argv[0];
    
    	// Process command line arguments
    	// ignore argv[0]
    	argc--;
    	argv++;
    
    	// Everything up to '--' or first non '-' arg goes to the vm
    
    	int i = runtime.addVmArguments(argc, argv);
    
    	// Next arg is parent directory
    	if (i < argc) {
    		runtime.mParentDir = argv[i++];
    	}
    
    	// Next arg is startup classname or "--zygote"
    	if (i < argc) {
    		arg = argv[i++];
    		if (0 == strcmp("--zygote", arg)) {
    			bool startSystemServer = (i < argc) ?
    				strcmp(argv[i], "--start-system-server") == 0 : false;
    			setArgv0(argv0, "zygote");
    			set_process_name("zygote");
    			runtime.start("com.android.internal.os.ZygoteInit",
    				startSystemServer);
    		} else {
    			set_process_name(argv0);
    
    			runtime.mClassName = arg;
    
    			// Remainder of args get passed to startup class main()
    			runtime.mArgC = argc-i;
    			runtime.mArgV = argv+i;
    
    			LOGV("App process is starting with pid=%d, class=%s.\n",
    				getpid(), runtime.getClassName());
    			runtime.start();
    		}
    	} else {
    		LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    		fprintf(stderr, "Error: no class name or --zygote supplied.\n");
    		app_usage();
    		return 10;
    	}
    
    }
            這個函數的主要作用就是創建一個AppRuntime變量,然后調用它的start成員函數。AppRuntime這個類我們在Android應用程序進程啟動過程的源代碼分析一文中已經有過介紹了,它同樣是在frameworks/base/cmds/app_process/app_main.cpp文件中定義:

    class AppRuntime : public AndroidRuntime
    {
    	......
    };
            它約繼承于AndroidRuntime類, AndroidRuntime類定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

    ......
    
    static AndroidRuntime* gCurRuntime = NULL;
    
    ......
    
    AndroidRuntime::AndroidRuntime()
    {
    	......
    
    	assert(gCurRuntime == NULL);        // one per process
    	gCurRuntime = this;
    }
            當AppRuntime對象創建時,會調用其父類AndroidRuntime的構造函數,而在AndroidRuntime類的構造函數里面,會將this指針保存在靜態全局變量gCurRuntime中,這樣,當其它地方需要使用這個AppRuntime對象時,就可以通過同一個文件中的這個函數來獲取這個對象的指針:

    AndroidRuntime* AndroidRuntime::getRuntime()
    {
        return gCurRuntime;
    }
    
            回到上面的main函數中,由于我們在init.rc文件中,設置了app_process啟動參數--zygote和--start-system-server,因此,在main函數里面,最終會執行下面語句:

        runtime.start("com.android.internal.os.ZygoteInit",
    	startSystemServer);
            這里的參數startSystemServer為true,表示要啟動SystemServer組件。由于AppRuntime沒有實現自己的start函數,它繼承了父類AndroidRuntime的start函數,因此,下面會執行AndroidRuntime類的start函數。

            Step 2. AndroidRuntime.start

            這個函數定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

    /*
    * Start the Android runtime.  This involves starting the virtual machine
    * and calling the "static void main(String[] args)" method in the class
    * named by "className".
    */
    void AndroidRuntime::start(const char* className, const bool startSystemServer)
    {
    	......
    
    	char* slashClassName = NULL;
    	char* cp;
    	JNIEnv* env;
    
    	......
    
    	/* start the virtual machine */
    	if (startVm(&mJavaVM, &env) != 0)
    		goto bail;
    
    	/*
    	* Register android functions.
    	*/
    	if (startReg(env) < 0) {
    		LOGE("Unable to register all android natives\n");
    		goto bail;
    	}
    
    	/*
    	* We want to call main() with a String array with arguments in it.
    	* At present we only have one argument, the class name.  Create an
    	* array to hold it.
    	*/
    	jclass stringClass;
    	jobjectArray strArray;
    	jstring classNameStr;
    	jstring startSystemServerStr;
    	stringClass = env->FindClass("java/lang/String");
    	assert(stringClass != NULL);
    	strArray = env->NewObjectArray(2, stringClass, NULL);
    	assert(strArray != NULL);
    	classNameStr = env->NewStringUTF(className);
    	assert(classNameStr != NULL);
    	env->SetObjectArrayElement(strArray, 0, classNameStr);
    	startSystemServerStr = env->NewStringUTF(startSystemServer ?
    		"true" : "false");
    	env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
    
    	/*
    	* Start VM.  This thread becomes the main thread of the VM, and will
    	* not return until the VM exits.
    	*/
    	jclass startClass;
    	jmethodID startMeth;
    
    	slashClassName = strdup(className);
    	for (cp = slashClassName; *cp != '\0'; cp++)
    		if (*cp == '.')
    			*cp = '/';
    
    	startClass = env->FindClass(slashClassName);
    	if (startClass == NULL) {
    		......
    	} else {
    		startMeth = env->GetStaticMethodID(startClass, "main",
    			"([Ljava/lang/String;)V");
    		if (startMeth == NULL) {
    			......
    		} else {
    			env->CallStaticVoidMethod(startClass, startMeth, strArray);
    			......
    		}
    	}
    
    	......
    }

            這個函數的作用是啟動Android系統運行時庫,它主要做了三件事情,一是調用函數startVM啟動虛擬機,二是調用函數startReg注冊JNI方法,三是調用了com.android.internal.os.ZygoteInit類的main函數。

            Step 3. ZygoteInit.main

            這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

     

    public class ZygoteInit {
    	......
    
    	public static void main(String argv[]) {
    		try {
    			......
    
    			registerZygoteSocket();
    			
    			......
    
    			......
    
    			if (argv[1].equals("true")) {
    				startSystemServer();
    			} else if (!argv[1].equals("false")) {
    				......
    			}
    
    			......
    
    			if (ZYGOTE_FORK_MODE) {
    				......
    			} else {
    				runSelectLoopMode();
    			}
    
    			......
    		} catch (MethodAndArgsCaller caller) {
    			......
    		} catch (RuntimeException ex) {
    			......
    		}
    	}
    
    	......
    }
             它主要作了三件事情,一個調用registerZygoteSocket函數創建了一個socket接口,用來和ActivityManagerService通訊,二是調用startSystemServer函數來啟動SystemServer組件,三是調用runSelectLoopMode函數進入一個無限循環在前面創建的socket接口上等待ActivityManagerService請求創建新的應用程序進程。

     

             Step 4. ZygoteInit.registerZygoteSocket

             這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	/**
    	* Registers a server socket for zygote command connections
    	*
    	* @throws RuntimeException when open fails
    	*/
    	private static void registerZygoteSocket() {
    		if (sServerSocket == null) {
    			int fileDesc;
    			try {
    				String env = System.getenv(ANDROID_SOCKET_ENV);
    				fileDesc = Integer.parseInt(env);
    			} catch (RuntimeException ex) {
    				......
    			}
    
    			try {
    				sServerSocket = new LocalServerSocket(
    					createFileDescriptor(fileDesc));
    			} catch (IOException ex) {
    				.......
    			}
    		}
    	}
    		
    	......
    }
             這個socket接口是通過文件描述符來創建的,這個文件描符代表的就是我們前面說的/dev/socket/zygote文件了。這個文件描述符是通過環境變量ANDROID_SOCKET_ENV得到的,它定義為:

     

     

    public class ZygoteInit {
    	......
    
    	private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
    		
    	......
    }
            那么,這個環境變量的值又是由誰來設置的呢?我們知道,系統啟動腳本文件system/core/rootdir/init.rc是由init進程來解釋執行的,而init進程的源代碼位于system/core/init目錄中,在init.c文件中,是由service_start函數來解釋init.rc文件中的service命令的:

     

     

    void service_start(struct service *svc, const char *dynamic_args)
    {
    	......
    
    	pid_t pid;
    
    	......
    
    	pid = fork();
    
    	if (pid == 0) {
    		struct socketinfo *si;
    
    		......
    
    		for (si = svc->sockets; si; si = si->next) {
    			int socket_type = (
    				!strcmp(si->type, "stream") ? SOCK_STREAM :
    				(!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
    			int s = create_socket(si->name, socket_type,
    				si->perm, si->uid, si->gid);
    			if (s >= 0) {
    				publish_socket(si->name, s);
    			}
    		}
    
    		......
    	}
    
    	......
    }
            每一個service命令都會促使init進程調用fork函數來創建一個新的進程,在新的進程里面,會分析里面的socket選項,對于每一個socket選項,都會通過create_socket函數來在/dev/socket目錄下創建一個文件,在這個場景中,這個文件便是zygote了,然后得到的文件描述符通過publish_socket函數寫入到環境變量中去:

     

     

    static void publish_socket(const char *name, int fd)
    {
        char key[64] = ANDROID_SOCKET_ENV_PREFIX;
        char val[64];
    
        strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
                name,
                sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
        snprintf(val, sizeof(val), "%d", fd);
        add_environment(key, val);
    
        /* make sure we don't close-on-exec */
        fcntl(fd, F_SETFD, 0);
    }
    
           這里傳進來的參數name值為"zygote",而ANDROID_SOCKET_ENV_PREFIX在system/core/include/cutils/sockets.h定義為:

     

     

    #define ANDROID_SOCKET_ENV_PREFIX	"ANDROID_SOCKET_"
    
            因此,這里就把上面得到的文件描述符寫入到以"ANDROID_SOCKET_zygote"為key值的環境變量中。又因為上面的ZygoteInit.registerZygoteSocket函數與這里創建socket文件的create_socket函數是運行在同一個進程中,因此,上面的ZygoteInit.registerZygoteSocket函數可以直接使用這個文件描述符來創建一個Java層的LocalServerSocket對象。如果其它進程也需要打開這個/dev/socket/zygote文件來和Zygote進程進行通信,那就必須要通過文件名來連接這個LocalServerSocket了,參考Android應用程序進程啟動過程的源代碼分析一文中的Step 4,ActivityManagerService是通過Process.start函數來創建一個新的進程的,而Process.start函數會首先通過Socket連接到Zygote進程中,最終由Zygote進程來完成創建新的應用程序進程,而Process類是通過openZygoteSocketIfNeeded函數來連接到Zygote進程中的Socket的:

     

     

    public class Process {  
    	......  
     
    	private static void openZygoteSocketIfNeeded()  
    			throws ZygoteStartFailedEx {  
    
    		......
    
    		for (int retry = 0  
    			; (sZygoteSocket == null) && (retry < (retryCount + 1))  
    			; retry++ ) {  
    
    				......
    
    				try {  
    					sZygoteSocket = new LocalSocket();  
    					sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,  
    						LocalSocketAddress.Namespace.RESERVED));  
    
    					sZygoteInputStream  
    						= new DataInputStream(sZygoteSocket.getInputStream());  
    
    					sZygoteWriter =  
    						new BufferedWriter(  
    						new OutputStreamWriter(  
    						sZygoteSocket.getOutputStream()),  
    						256);  
    
    					......  
    				} catch (IOException ex) {  
    					......  
    				}  
    		}  
    
    		......  
    	}  
    
    	......  
    }
            這里的ZYGOTE_SOCKET定義為:

     

     

    public class Process {  
    	......  
     
    	private static final String ZYGOTE_SOCKET = "zygote";  
    
    	......  
    } 
            它剛好就是對應/dev/socket目錄下的zygote文件了。

     

            Android系統中的socket機制和binder機制一樣,都是可以用來進行進程間通信,讀者可以自己對比一下這兩者的不同之處,Binder進程間通信機制可以參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃一文。

           Socket對象創建完成之后,回到Step 3中的ZygoteInit.main函數中,startSystemServer函數來啟動SystemServer組件。

           Step 5. ZygoteInit.startSystemServer
           這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

     

    public class ZygoteInit {
    	......
    
    	private static boolean startSystemServer()
    			throws MethodAndArgsCaller, RuntimeException {
    		/* Hardcoded command line to start the system server */
    		String args[] = {
    			"--setuid=1000",
    			"--setgid=1000",
    			"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
    			"--capabilities=130104352,130104352",
    			"--runtime-init",
    			"--nice-name=system_server",
    			"com.android.server.SystemServer",
    		};
    		ZygoteConnection.Arguments parsedArgs = null;
    
    		int pid;
    
    		try {
    			parsedArgs = new ZygoteConnection.Arguments(args);
    
    			......
    
    			/* Request to fork the system server process */
    			pid = Zygote.forkSystemServer(
    				parsedArgs.uid, parsedArgs.gid,
    				parsedArgs.gids, debugFlags, null,
    				parsedArgs.permittedCapabilities,
    				parsedArgs.effectiveCapabilities);
    		} catch (IllegalArgumentException ex) {
    			......
    		}
    
    		/* For child process */
    		if (pid == 0) {
    			handleSystemServerProcess(parsedArgs);
    		}
    
    		return true;
    	}
    	
    	......
    }
            這里我們可以看到,Zygote進程通過Zygote.forkSystemServer函數來創建一個新的進程來啟動SystemServer組件,返回值pid等0的地方就是新的進程要執行的路徑,即新創建的進程會執行handleSystemServerProcess函數。

     

            Step 6. ZygoteInit.handleSystemServerProcess
            這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	private static void handleSystemServerProcess(
    			ZygoteConnection.Arguments parsedArgs)
    			throws ZygoteInit.MethodAndArgsCaller {
    		closeServerSocket();
    
    		/*
    		* Pass the remaining arguments to SystemServer.
    		* "--nice-name=system_server com.android.server.SystemServer"
    		*/
    		RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
    		/* should never reach here */
    	}
    
    	......
    } 
            由于由Zygote進程創建的子進程會繼承Zygote進程在前面Step 4中創建的Socket文件描述符,而這里的子進程又不會用到它,因此,這里就調用closeServerSocket函數來關閉它。這個函數接著調用RuntimeInit.zygoteInit函數來進一步執行啟動SystemServer組件的操作。

     

            Step 7. RuntimeInit.zygoteInit

            這個函數定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

     

    public class RuntimeInit {  
    	......  
    
    	public static final void zygoteInit(String[] argv)  
    			throws ZygoteInit.MethodAndArgsCaller {  
    		......  
      
    		zygoteInitNative();  
    
    		......  
    
    
    		// Remaining arguments are passed to the start class's static main  
    
    		String startClass = argv[curArg++];  
    		String[] startArgs = new String[argv.length - curArg];  
    
    		System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);  
    		invokeStaticMain(startClass, startArgs);  
    	}  
    
    	......  
    }
             這個函數會執行兩個操作,一個是調用zygoteInitNative函數來執行一個Binder進程間通信機制的初始化工作,這個工作完成之后,這個進程中的Binder對象就可以方便地進行進程間通信了,另一個是調用上面Step 5傳進來的com.android.server.SystemServer類的main函數。

     

             Step 8. RuntimeInit.zygoteInitNative

             這個函數定義在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

     

    public class RuntimeInit {  
    	......  
    
    	public static final native void zygoteInitNative();  
    
    	......  
    }
            這里可以看出,函數zygoteInitNative是一個Native函數,實現在frameworks/base/core/jni/AndroidRuntime.cpp文件中,這里我們就不再細看了,具體可以參考Android應用程序進程啟動過程的源代碼分析一文的Step 9,完成這一步后,這個進程的Binder進程間通信機制基礎設施就準備好了。

     

            回到Step 7中的RuntimeInit.zygoteInitNative函數,下一步它就要執行com.android.server.SystemServer類的main函數了。

            Step 9. SystemServer.main

            這個函數定義在frameworks/base/services/java/com/android/server/SystemServer.java文件中:

     

    public class SystemServer  
    {  
    	......  
    
    	native public static void init1(String[] args);  
    
    	......  
    
    	public static void main(String[] args) {  
    		......  
    
    		init1(args);  
    
    		......  
    	} 
    
    	public static final void init2() {  
    		Slog.i(TAG, "Entered the Android system server!");  
    		Thread thr = new ServerThread();  
    		thr.setName("android.server.ServerThread");  
    		thr.start();  
    	}  
    
    	......  
    }
            這里的main函數首先會執行JNI方法init1,然后init1會調用這里的init2函數,在init2函數里面,會創建一個ServerThread線程對象來執行一些系統關鍵服務的啟動操作,例如我們在前面兩篇文章Android應用程序安裝過程源代碼分析Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析中提到的PackageManagerService和ActivityManagerService。
            這一步的具體執行過程可以參考Android應用程序安裝過程源代碼分析一文,這里就不再詳述了。

     

            這里執行完成后,層層返回,最后回到上面的Step 3中的ZygoteInit.main函數中,接下來它就要調用runSelectLoopMode函數進入一個無限循環在前面Step 4中創建的socket接口上等待ActivityManagerService請求創建新的應用程序進程了。

            Step 10. ZygoteInit.runSelectLoopMode

            這個函數定義在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	private static void runSelectLoopMode() throws MethodAndArgsCaller {
    		ArrayList<FileDescriptor> fds = new ArrayList();
    		ArrayList<ZygoteConnection> peers = new ArrayList();
    		FileDescriptor[] fdArray = new FileDescriptor[4];
    
    		fds.add(sServerSocket.getFileDescriptor());
    		peers.add(null);
    
    		int loopCount = GC_LOOP_COUNT;
    		while (true) {
    			int index;
    
    			......
    
    
    			try {
    				fdArray = fds.toArray(fdArray);
    				index = selectReadable(fdArray);
    			} catch (IOException ex) {
    				throw new RuntimeException("Error in select()", ex);
    			}
    
    			if (index < 0) {
    				throw new RuntimeException("Error in select()");
    			} else if (index == 0) {
    				ZygoteConnection newPeer = acceptCommandPeer();
    				peers.add(newPeer);
    				fds.add(newPeer.getFileDesciptor());
    			} else {
    				boolean done;
    				done = peers.get(index).runOnce();
    
    				if (done) {
    					peers.remove(index);
    					fds.remove(index);
    				}
    			}
    		}
    	}
    
    	......
    }      
            這個函數我們已經在Android應用程序進程啟動過程的源代碼分析一文的Step 5中分析過了,這就是在等待ActivityManagerService來連接這個Socket,然后調用ZygoteConnection.runOnce函數來創建新的應用程序,有興趣的讀者可以參考Android應用程序進程啟動過程的源代碼分析這篇文章,這里就不再詳述了。

            這樣,Zygote進程就啟動完成了,學習到這里,我們終于都對Android系統中的進程有了一個深刻的認識了,這里總結一下:

            1. 系統啟動時init進程會創建Zygote進程,Zygote進程負責后續Android應用程序框架層的其它進程的創建和啟動工作。

            2. Zygote進程會首先創建一個SystemServer進程,SystemServer進程負責啟動系統的關鍵服務,如包管理服務PackageManagerService和應用程序組件管理服務ActivityManagerService。

            3. 當我們需要啟動一個Android應用程序時,ActivityManagerService會通過Socket進程間通信機制,通知Zygote進程為這個應用程序創建一個新的進程。

     

    作者:Luoshengyang 發表于2011-9-19 0:59:08 原文鏈接
    閱讀:5235 評論:8 查看評論
    posted on 2012-04-17 21:32 mixer-a 閱讀(559) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 免费人成视频x8x8入口| 永久在线毛片免费观看| 日本亚洲国产一区二区三区 | 亚洲AV色香蕉一区二区| 最近国语视频在线观看免费播放| 无码专区一va亚洲v专区在线| 国产亚洲综合视频| 亚洲国产综合精品一区在线播放| 亚洲av纯肉无码精品动漫| 国产无遮挡吃胸膜奶免费看| 国产精品亚洲专区一区| 亚洲国产成人久久一区久久| 在线免费视频你懂的| 国产亚洲精久久久久久无码| 少妇人妻偷人精品免费视频| 久久精品国产亚洲AV大全| 国产精品色拉拉免费看| 亚洲成a人片在线不卡一二三区| 国产视频精品免费| 成人无码视频97免费| 亚洲午夜在线电影| 性做久久久久久久免费看| 亚洲国产成人无码AV在线影院| 免费中文字幕在线| 免费人成在线观看视频高潮| 中文字幕亚洲综合精品一区| 好吊妞在线成人免费| 免费一区二区三区在线视频| 亚洲jjzzjjzz在线观看| 日本免费人成视频播放| 精品久久久久久国产免费了| 亚洲综合亚洲国产尤物| 免费看美女让人桶尿口| a在线视频免费观看| 亚洲不卡1卡2卡三卡2021麻豆| 免费人妻av无码专区| 日韩午夜理论免费TV影院| 人人狠狠综合久久亚洲| 亚洲成在人天堂在线| 国产免费卡一卡三卡乱码| 亚洲午夜成激人情在线影院|