<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專(zhuān)注安卓開(kāi)發(fā)

      導(dǎo)航

      Android包管理機(jī)制(一) PackageInstaller的初始化

      包管理機(jī)制是Android中的重要機(jī)制,是應(yīng)用開(kāi)發(fā)和系統(tǒng)開(kāi)發(fā)需要掌握的知識(shí)點(diǎn)之一。
      包指的是Apk、jar和so文件等等,它們被加載到Android內(nèi)存中,由一個(gè)包轉(zhuǎn)變成可執(zhí)行的代碼,這就需要一個(gè)機(jī)制來(lái)進(jìn)行包的加載、解析、管理等操作,這就是包管理機(jī)制。包管理機(jī)制由許多類(lèi)一起組成,其中核心為PackageManagerService(PMS),它負(fù)責(zé)對(duì)包進(jìn)行管理,如果直接講PMS會(huì)比較難以理解,因此我們需要一個(gè)切入點(diǎn),這個(gè)切入點(diǎn)就是常見(jiàn)的APK的安裝。
      講到APK的安裝之前,先了解下PackageManager、APK文件結(jié)構(gòu)和安裝方式。

      1.PackageManager簡(jiǎn)介

      與ActivityManager和AMS的關(guān)系類(lèi)似,PMS也有一個(gè)對(duì)應(yīng)的管理類(lèi)PackageManager,用于向應(yīng)用程序進(jìn)程提供一些功能。PackageManager是一個(gè)抽象類(lèi),它的具體實(shí)現(xiàn)類(lèi)為ApplicationPackageManager,ApplicationPackageManager中的方法會(huì)通過(guò)IPackageManager與AMS進(jìn)行進(jìn)程間通信,因此PackageManager所提供的功能最終是由PMS來(lái)實(shí)現(xiàn)的,這么設(shè)計(jì)的主要用意是為了避免系統(tǒng)服務(wù)PMS直接被訪問(wèn)。PackageManager提供了一些功能,主要有以下幾點(diǎn):

      1. 獲取一個(gè)應(yīng)用程序的所有信息(ApplicationInfo)。
      2. 獲取四大組件的信息。
      3. 查詢(xún)permission相關(guān)信息。
      4. 獲取包的信息。
      5. 安裝、卸載APK.

      2.APK文件結(jié)構(gòu)和安裝方式

      APK是AndroidPackage的縮寫(xiě),即Android安裝包,它實(shí)際上是zip格式的壓縮文件,一般情況下,解壓后的文件結(jié)構(gòu)如下表所示。

      目錄/文件描述
      assert 存放的原生資源文件,通過(guò)AssetManager類(lèi)訪問(wèn)。
      lib 存放庫(kù)文件。
      META-INF 保存應(yīng)用的簽名信息,簽名信息可以驗(yàn)證APK文件的完整性。
      res 存放資源文件。res中除了raw子目錄,其他的子目錄都參與編譯,這些子目錄下的資源是通過(guò)編譯出的R類(lèi)在代碼中訪問(wèn)。
      AndroidManifest.xml 用來(lái)聲明應(yīng)用程序的包名稱(chēng)、版本、組件和權(quán)限等數(shù)據(jù)。 apk中的AndroidManifest.xml經(jīng)過(guò)壓縮,可以通過(guò)AXMLPrinter2工具解開(kāi)。
      classes.dex Java源碼編譯后生成的Java字節(jié)碼文件。
      resources.arsc 編譯后的二進(jìn)制資源文件。

      APK的安裝場(chǎng)景主要有以下幾種:

      • 通過(guò)adb命令安裝:adb 命令包括adb push/install
      • 通過(guò)系統(tǒng)安裝器packageinstaller進(jìn)行安裝:packageinstaller是系統(tǒng)內(nèi)置的應(yīng)用程序,用于安裝和卸載應(yīng)用程序。
      • 系統(tǒng)應(yīng)用安裝
      • 應(yīng)用商店自動(dòng)安裝

      這4種方式最終都會(huì)調(diào)用PMS的scanPackageDirtyLI方法用來(lái)解析包,在此之前的調(diào)用鏈?zhǔn)遣煌模酒恼聲?huì)介紹第二種方式,對(duì)于用戶(hù)來(lái)說(shuō),這是最常用的安裝方式;對(duì)于開(kāi)發(fā)者來(lái)說(shuō),這是調(diào)用鏈比較長(zhǎng)的安裝方式,能學(xué)到的更多。其他的安裝場(chǎng)景會(huì)在本系列的后續(xù)文章進(jìn)行講解。

      3.尋找PackageInstaller入口

      在Android7.0之前我們可以通過(guò)如下代碼安裝指定路徑中的APK。

      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      intent.setDataAndType(Uri.parse("file://" + path),"application/vnd.android.package-archive");
      context.startActivity(intent);
      View Code

        但是Android7.0或更高版本再這么做,就會(huì)報(bào)FileUriExposedException異常。這是因?yàn)镾trictMode API 政策禁止應(yīng)用程序?qū)ile:// Uri暴露給另一個(gè)應(yīng)用程序,如果包含file:// Uri的 intent 離開(kāi)你的應(yīng)用,就會(huì)報(bào)FileUriExposedException 異常。為了解決這個(gè)問(wèn)題,谷歌提供了FileProvider,F(xiàn)ileProvider繼承自ContentProvider ,使用它可以將file://Uri替換為content://Uri,具體怎么使用FileProvider并不是本文的重點(diǎn),只要知道無(wú)論是Android7.0之前還是Android7.0以及更高版本,都會(huì)調(diào)用如下代碼:

      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setDataAndType(xxxxx, "application/vnd.android.package-archive");
      View Code

      Intent的Action屬性為ACTION_VIEW,Type屬性指定Intent的數(shù)據(jù)類(lèi)型為application/vnd.android.package-archive。
      能隱式匹配的Activity為InstallStart,需要注意的是,這里分析的源碼基于Android8.0,7.0能隱式匹配的Activity為PackageInstallerActivity。
      packages/apps/PackageInstaller/AndroidManifest.xml

      <activity android:name=".InstallStart"
                     android:exported="true"
                     android:excludeFromRecents="true">
                 <intent-filter android:priority="1">
                     <action android:name="android.intent.action.VIEW" />
                     <action android:name="android.intent.action.INSTALL_PACKAGE" />
                     <category android:name="android.intent.category.DEFAULT" />
                     <data android:scheme="file" />
                     <data android:scheme="content" />
                     <data android:mimeType="application/vnd.android.package-archive" />
                 </intent-filter>
              ...
      </activity>
      View Code

      InstallStart是PackageInstaller中的入口Activity,其中PackageInstaller是系統(tǒng)內(nèi)置的應(yīng)用程序,用于安裝和卸載應(yīng)用。當(dāng)我們調(diào)用PackageInstaller來(lái)安裝應(yīng)用時(shí)會(huì)跳轉(zhuǎn)到InstallStart,并調(diào)用它的onCreate方法:
      packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStart.java

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
               if (PackageInstaller.ACTION_CONFIRM_PERMISSIONS.equals(intent.getAction())) {//1
                nextActivity.setClass(this, PackageInstallerActivity.class);
            } else {
                Uri packageUri = intent.getData();
                if (packageUri == null) {//2
                    Intent result = new Intent();
                    result.putExtra(Intent.EXTRA_INSTALL_RESULT,
                            PackageManager.INSTALL_FAILED_INVALID_URI);
                    setResult(RESULT_FIRST_USER, result);
                    nextActivity = null;
                } else {
                    if (packageUri.getScheme().equals(SCHEME_CONTENT)) {//3
                        nextActivity.setClass(this, InstallStaging.class);
                    } else {
                        nextActivity.setClass(this, PackageInstallerActivity.class);
                    }
                }
            }
            if (nextActivity != null) {
                startActivity(nextActivity);
            }
            finish();
        }
      View Code

      注釋1處判斷Intent的Action是否為CONFIRM_PERMISSIONS,根據(jù)本文的應(yīng)用情景顯然不是,接著往下看,注釋2處判斷packageUri 是否為空也不成立,注釋3處,判斷Uri的Scheme協(xié)議是否是content,如果是就跳轉(zhuǎn)到InstallStaging,如果不是就跳轉(zhuǎn)到PackageInstallerActivity。本文的應(yīng)用情景中,Android7.0以及更高版本我們會(huì)使用FileProvider來(lái)處理URI ,F(xiàn)ileProvider會(huì)隱藏共享文件的真實(shí)路徑,將路徑轉(zhuǎn)換成content://Uri路徑,這樣就會(huì)跳轉(zhuǎn)到InstallStaging。InstallStaging的onResume方法如下所示。

      packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java

      @Override
      protected void onResume() {
            super.onResume();
            if (mStagingTask == null) {
                if (mStagedFile == null) {
                    try {
                        mStagedFile = TemporaryFileManager.getStagedFile(this);//1
                    } catch (IOException e) {
                        showError();
                        return;
                    }
                }
                mStagingTask = new StagingAsyncTask();
                mStagingTask.execute(getIntent().getData());//2
            }
        }
      View Code

      注釋1處如果File類(lèi)型的mStagedFile 為null,則創(chuàng)建mStagedFile ,mStagedFile用于存儲(chǔ)臨時(shí)數(shù)據(jù)。 注釋2處啟動(dòng)StagingAsyncTask,并傳入了content協(xié)議的Uri,如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java

      private final class StagingAsyncTask extends AsyncTask<Uri, Void, Boolean> {
              @Override
              protected Boolean doInBackground(Uri... params) {
                  if (params == null || params.length <= 0) {
                      return false;
                  }
                  Uri packageUri = params[0];
                  try (InputStream in = getContentResolver().openInputStream(packageUri)) {
                      if (in == null) {
                          return false;
                      }
                      try (OutputStream out = new FileOutputStream(mStagedFile)) {
                          byte[] buffer = new byte[4096];
                          int bytesRead;
                          while ((bytesRead = in.read(buffer)) >= 0) {
                              if (isCancelled()) {
                                  return false;
                              }
                              out.write(buffer, 0, bytesRead);
                          }
                      }
                  } catch (IOException | SecurityException e) {
                      Log.w(LOG_TAG, "Error staging apk from content URI", e);
                      return false;
                  }
                  return true;
              }
              @Override
              protected void onPostExecute(Boolean success) {
                  if (success) {
                      Intent installIntent = new Intent(getIntent());
                      installIntent.setClass(InstallStaging.this, PackageInstallerActivity.class);
                      installIntent.setData(Uri.fromFile(mStagedFile));
                      installIntent
                              .setFlags(installIntent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                      installIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                      startActivityForResult(installIntent, 0);
                  } else {
                      showError();
                  }
              }
          }
      }
      View Code

      doInBackground方法中將packageUri(content協(xié)議的Uri)的內(nèi)容寫(xiě)入到mStagedFile中,如果寫(xiě)入成功,onPostExecute方法中會(huì)跳轉(zhuǎn)到PackageInstallerActivity中,并將mStagedFile傳進(jìn)去。繞了一圈又回到了PackageInstallerActivity,這里可以看出InstallStaging主要起了轉(zhuǎn)換的作用,將content協(xié)議的Uri轉(zhuǎn)換為File協(xié)議,然后跳轉(zhuǎn)到PackageInstallerActivity,這樣就可以像此前版本(Android7.0之前)一樣啟動(dòng)安裝流程了。

      4.PackageInstallerActivity解析

      從功能上來(lái)說(shuō),PackageInstallerActivity才是應(yīng)用安裝器PackageInstaller真正的入口Activity,PackageInstallerActivity的onCreate方法如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

      @Override
      protected void onCreate(Bundle icicle) {
          super.onCreate(icicle);
          if (icicle != null) {
              mAllowUnknownSources = icicle.getBoolean(ALLOW_UNKNOWN_SOURCES_KEY);
          }
          mPm = getPackageManager();
          mIpm = AppGlobals.getPackageManager();
          mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
          mInstaller = mPm.getPackageInstaller();
          mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
          ...
          //根據(jù)Uri的Scheme進(jìn)行預(yù)處理
          boolean wasSetUp = processPackageUri(packageUri);//1
          if (!wasSetUp) {
              return;
          }
          bindUi(R.layout.install_confirm, false);
          //判斷是否是未知來(lái)源的應(yīng)用,如果開(kāi)啟允許安裝未知來(lái)源選項(xiàng)則直接初始化安裝
          checkIfAllowedAndInitiateInstall();//2
      }
      View Code

      首先初始話安裝所需要的各種對(duì)象,比如PackageManager、IPackageManager、AppOpsManager和UserManager等等,它們的描述如下表所示。

      類(lèi)名描述
      PackageManager 用于向應(yīng)用程序進(jìn)程提供一些功能,最終的功能是由PMS來(lái)實(shí)現(xiàn)的
      IPackageManager 一個(gè)AIDL的接口,用于和PMS進(jìn)行進(jìn)程間通信
      AppOpsManager 用于權(quán)限動(dòng)態(tài)檢測(cè),在Android4.3中被引入
      PackageInstaller 提供安裝、升級(jí)和刪除應(yīng)用程序功能
      UserManager 用于多用戶(hù)管理

      注釋1處的processPackageUri方法如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

      private boolean processPackageUri(final Uri packageUri) {
           mPackageURI = packageUri;
           final String scheme = packageUri.getScheme();//1
           switch (scheme) {
               case SCHEME_PACKAGE: {
                   try {
                    ...
               } break;
               case SCHEME_FILE: {
                   File sourceFile = new File(packageUri.getPath());//1
                   //得到sourceFile的包信息
                   PackageParser.Package parsed = PackageUtil.getPackageInfo(this, sourceFile);//2
                   if (parsed == null) {
                       Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
                       showDialogInner(DLG_PACKAGE_ERROR);
                       setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
                       return false;
                   }
                   //對(duì)parsed進(jìn)行進(jìn)一步處理得到包信息PackageInfo
                   mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
                           PackageManager.GET_PERMISSIONS, 0, 0, null,
                           new PackageUserState());//3
                   mAppSnippet = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
               } break;
               default: {
                   Log.w(TAG, "Unsupported scheme " + scheme);
                   setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
                   finish();
                   return false;
               }
           }
           return true;
       }
      View Code

      首先在注釋1處得到packageUri的Scheme協(xié)議,接著根據(jù)這個(gè)Scheme協(xié)議分別對(duì)package協(xié)議和file協(xié)議進(jìn)行處理,如果不是這兩個(gè)協(xié)議就會(huì)關(guān)閉PackageInstallerActivity并return false。我們主要來(lái)看file協(xié)議的處理,注釋1處根據(jù)packageUri創(chuàng)建一個(gè)新的File。注釋2處的內(nèi)部會(huì)用PackageParser的parsePackage方法解析這個(gè)File(這個(gè)File其實(shí)是APK文件),得到APK的包信息Package ,Package包含了該APK的所有信息。注釋3處會(huì)將Package根據(jù)uid、用戶(hù)狀態(tài)信息和PackageManager的配置等變量對(duì)包信息Package做進(jìn)一步處理得到PackageInfo。
      回到PackageInstallerActivity的onCreate方法的注釋2處,checkIfAllowedAndInitiateInstall方法如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

      private void checkIfAllowedAndInitiateInstall() {
             //判斷如果允許安裝未知來(lái)源或者根據(jù)Intent判斷得出該APK不是未知來(lái)源
             if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) {//1
                 //初始化安裝
                 initiateInstall();//2
                 return;
             }
             // 如果管理員限制來(lái)自未知源的安裝, 就彈出提示Dialog或者跳轉(zhuǎn)到設(shè)置界面
             if (isUnknownSourcesDisallowed()) {
                 if ((mUserManager.getUserRestrictionSource(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
                         Process.myUserHandle()) & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {    
                     showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);
                     return;
                 } else {
                     startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
                     finish();
                 }
             } else {
                 handleUnknownSources();//3
             }
         }
      View Code

      注釋1處判斷允許安裝未知來(lái)源或者根據(jù)Intent判斷得出該APK不是未知來(lái)源,就調(diào)用注釋2處的initiateInstall方法來(lái)初始化安裝。如果管理員限制來(lái)自未知源的安裝, 就彈出提示Dialog或者跳轉(zhuǎn)到設(shè)置界面,否則就調(diào)用注釋3處的handleUnknownSources方法來(lái)處理未知來(lái)源的APK。注釋2處的initiateInstall方法如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

      private void initiateInstall() {
            String pkgName = mPkgInfo.packageName;//1
            String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
            if (oldName != null && oldName.length > 0 && oldName[0] != null) {
                pkgName = oldName[0];
                mPkgInfo.packageName = pkgName;
                mPkgInfo.applicationInfo.packageName = pkgName;
            }
            try {
                //根據(jù)包名獲取應(yīng)用程序信息
                mAppInfo = mPm.getApplicationInfo(pkgName,
                        PackageManager.MATCH_UNINSTALLED_PACKAGES);//2
                if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
                    mAppInfo = null;
                }
            } catch (NameNotFoundException e) {
                mAppInfo = null;
            }
            //初始化安裝確認(rèn)界面
            startInstallConfirm();//3
        }
      View Code

      注釋1處得到包名,注釋2處根據(jù)包名獲取獲取應(yīng)用程序信息ApplicationInfo。注釋3處的startInstallConfirm方法如下所示。
      packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java

      private void startInstallConfirm() {
          //省略初始化界面代碼
           ...
           AppSecurityPermissions perms = new AppSecurityPermissions(this, mPkgInfo);//1
           final int N = perms.getPermissionCount(AppSecurityPermissions.WHICH_ALL);
           if (mAppInfo != null) {
               msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                       ? R.string.install_confirm_question_update_system
                       : R.string.install_confirm_question_update;
               mScrollView = new CaffeinatedScrollView(this);
               mScrollView.setFillViewport(true);
               boolean newPermissionsFound = false;
               if (!supportsRuntimePermissions) {
                   newPermissionsFound =
                           (perms.getPermissionCount(AppSecurityPermissions.WHICH_NEW) > 0);
                   if (newPermissionsFound) {
                       permVisible = true;
                       mScrollView.addView(perms.getPermissionsView(
                               AppSecurityPermissions.WHICH_NEW));//2
                   }
               }
           ...
       }
      View Code

      startInstallConfirm方法中首先初始化安裝確認(rèn)界面,就是我們平常安裝APK時(shí)出現(xiàn)的界面,界面上有確認(rèn)和取消按鈕并會(huì)列出安裝該APK需要訪問(wèn)的系統(tǒng)權(quán)限。需要注意的是,不同廠商定制的Android系統(tǒng)會(huì)有不同的安裝確認(rèn)界面。
      注釋1處會(huì)創(chuàng)建AppSecurityPermissions,它會(huì)提取出APK中權(quán)限信息并展示出來(lái),這個(gè)負(fù)責(zé)展示的View是AppSecurityPermissions的內(nèi)部類(lèi)PermissionItemView。注釋2處調(diào)用AppSecurityPermissions的getPermissionsView方法來(lái)獲取PermissionItemView,并將PermissionItemView添加到CaffeinatedScrollView中,這樣安裝該APK需要訪問(wèn)的系統(tǒng)權(quán)限就可以全部的展示出來(lái)了,PackageInstaller的初始化工作就完成了。

      5.總結(jié)

      現(xiàn)在來(lái)總結(jié)下PackageInstaller初始化的過(guò)程:

      1. 根據(jù)Uri的Scheme協(xié)議不同,跳轉(zhuǎn)到不同的界面,content協(xié)議跳轉(zhuǎn)到InstallStart,其他的跳轉(zhuǎn)到PackageInstallerActivity。本文應(yīng)用場(chǎng)景中,如果是Android7.0以及更高版本會(huì)跳轉(zhuǎn)到InstallStart。
      2. InstallStart將content協(xié)議的Uri轉(zhuǎn)換為File協(xié)議,然后跳轉(zhuǎn)到PackageInstallerActivity。
      3. PackageInstallerActivity會(huì)分別對(duì)package協(xié)議和file協(xié)議的Uri進(jìn)行處理,如果是file協(xié)議會(huì)解析APK文件得到包信息PackageInfo。
      4. PackageInstallerActivity中會(huì)對(duì)未知來(lái)源進(jìn)行處理,如果允許安裝未知來(lái)源或者根據(jù)Intent判斷得出該APK不是未知來(lái)源,就會(huì)初始化安裝確認(rèn)界面,如果管理員限制來(lái)自未知源的安裝, 就彈出提示Dialog或者跳轉(zhuǎn)到設(shè)置界面。

      PackageInstaller的初始化就講到這,關(guān)于PackageInstaller的安裝APK的過(guò)程會(huì)在本系列的下一篇文章進(jìn)行講解。

       

      posted on 2018-07-15 12:35  安卓筆記俠  閱讀(3156)  評(píng)論(0)    收藏  舉報(bào)

      主站蜘蛛池模板: 国产精品自拍一二三四区| 亚洲国产av一区二区| 精品国产中文字幕在线| 中文字幕国产精品日韩| 日本黄页网站免费大全| 4480yy亚洲午夜私人影院剧情| 兴义市| 少妇伦子伦精品无吗| 日本高清不卡一区二区三| 新版资源天堂中文| 被黑人巨大一区二区三区| 国产乱码1卡二卡3卡四卡5| 欧美人与zoxxxx另类| 无码中文字幕热热久久| 乱人伦中文字幕成人网站在线| 性欧洲大肥性欧洲大肥女 | 在线涩涩免费观看国产精品| 一边吃奶一边摸做爽视频| 狠狠综合久久综合88亚洲| 日韩熟女熟妇久久精品综合| 999国产精品一区二区| 免费无码VA一区二区三区| 石城县| 日韩熟妇| 亚洲国产高清精品线久久| 亚洲欧洲一区二区精品| 99久久免费精品国产色| 国产免费高清69式视频在线观看| 国产91午夜福利精品| 国产av一区二区三区| 日韩中文字幕一区二区不卡| 精品日韩人妻中文字幕| 色吊丝永久性观看网站| 91精品亚洲一区二区三区| 久久综合色一综合色88| 国产精品久久中文字幕网| av永久天堂一区| 无码AV中文字幕久久专区| 精品偷自拍另类精品在线| 国产亚洲精品久久久久久青梅| 久久久www成人免费精品|