美文网首页
Android之PackageManagerService ap

Android之PackageManagerService ap

作者: 锄禾豆 | 来源:发表于2022-02-25 10:00 被阅读0次

业务场景

1.开机启动安装
2.通过adb安装
3.通过安装器安装
4.未知来源

研究

注:代码来自Android 10

frameworks/base/services/core/java/com/android/server/pm/
PackageManagerService.java
Installer.java
PackageInstallerService.java
PackageInstallerSession.java
PackageManagerShellCommand.java

frameworks/base/core/java/android/content/pm/
PackageInstaller.java

frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller
PackageInstallerActivity.java
Installlnstalling.java

frameworks/native/cmds/installd/
***

1.开机启动安装

PackageManagerService构造方法
scanDirLI
scanPackageChildLI
addForInitLI
scanPackageNewLI
scanPackageOnlyLI

注:
扫描提取对应的数据结构,其实就是安装

拓展
这里可以自定义安装目录,例如system/presetapp。实现的方法就是
scanDirLI传入对应参数即可

2.通过adb安装

adb shell pm install apk

PackageManagerService
    onShellCommand

PackageManagerShellCommand
    runInstall()
    doCreateSession --> 创建PackageInstallerSession,这里涉及安装器包名传参
    doWriteSplit 
    doCommitSession

PackageInstaller --> 接口类,实现类PackageInstallerService,可创建PackageInstallerSession对象
  .Session --> 接口类,实现类PackageInstallerSession
    commit
PackageInstallerSession
    commit
    commitNonStagedLocked

PackageManagerService
    installStage --> 创建InstallParams(extends HandlerParams)
    startCopy --> 可以进行安装卡控
    handleStartCopy --> 清除缓存,给安装提供足够的空间
    handleReturnCode -->  apk拷贝及安装
       InstallArgs.copyApk() --> FileInstallArgs apk拷贝
       processPendingInstall --> 安装
            processInstallRequestsAsync
                installPackagesTracedLI
                    installPackagesLI
                        preparePackageLI
                        scanPackageTracedLI
                        reconcilePackagesLocked
                        commitPackagesLocked
                        executePostCommitSteps --> 这里涉及的就是installed操作
    
注:
mInterface.getPackageInstaller() --> PackageInstallerService

拓展
这里可以限制apk安装,也可以理解只允许自己的安装器安装。

3.通过安装器安装

PackageInstaller

PackageInstallerActivity
Installlnstalling
InstallingAsyncTask
    PackageInstaller.Session session
    session.commit(pendingIntent.getIntentSender());

之后的流程关注adb shell pm安装

4.installd分析

注:
安装器和adb安装,最后都跑到installd中
adb shell service list可查对应的服务
adb shell 
cd /system/bin
可查installd

启动
frameworks/native/cmds/installd/installd.rc
installd.rc

运行:
frameworks/native/cmds/installd
installd.cpp
int main(const int argc, char *argv[]) {
    return android::installd::installd_main(argc, argv);
}

static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {
    ····
    if ((ret = InstalldNativeService::start()) != android::OK) {
        SLOGE("Unable to start InstalldNativeService: %d", ret);
        exit(1);
    }
    ····
}


InstalldNativeService.cpp
status_t InstalldNativeService::start() {
    IPCThreadState::self()->disableBackgroundScheduling(true);
    status_t ret = BinderService<InstalldNativeService>::publish();
    if (ret != android::OK) {
        return ret;
    }
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
    ps->giveThreadPoolName();
    return android::OK;
}
//BinderService<InstalldNativeService>::publish()
//这里就是注册服务的地方

BinderService.h
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);//注册服务
    }
    
注:
之前是socket通信,现在是binder通信。

客户端Installer.java
    public void onStart() {
        if (mIsolated) {
            mInstalld = null;
        } else {
            connect();
        }
    }

    private void connect() {
        IBinder binder = ServiceManager.getService("installd");
        if (binder != null) {
            try {
                binder.linkToDeath(new DeathRecipient() {
                    @Override
                    public void binderDied() {
                        Slog.w(TAG, "installd died; reconnecting");
                        connect();
                    }
                }, 0);
            } catch (RemoteException e) {
                binder = null;
            }
        }

        if (binder != null) {
            mInstalld = IInstalld.Stub.asInterface(binder);
            try {
                invalidateMounts();
            } catch (InstallerException ignored) {
            }
        } else {
            Slog.w(TAG, "installd not found; trying again");
            BackgroundThread.getHandler().postDelayed(() -> {
                connect();
            }, DateUtils.SECOND_IN_MILLIS);
        }
    }

5.未知来源检测

来源:
来源于PackageInstaller。涉及的类PackageInstallerActivity
ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage)

方法:
        final int appOpCode =
                AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
        final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode,
                mOriginatingUid, mOriginatingPackage);
        switch (appOpMode) {
            case AppOpsManager.MODE_DEFAULT:
                mAppOpsManager.setMode(appOpCode, mOriginatingUid,
                        mOriginatingPackage, AppOpsManager.MODE_ERRORED);
                // fall through
            case AppOpsManager.MODE_ERRORED:
                showDialogInner(DLG_EXTERNAL_SOURCE_BLOCKED);
                break;
            case AppOpsManager.MODE_ALLOWED:
                initiateInstall();
                break;
            default:
                Log.e(TAG, "Invalid app op mode " + appOpMode
                        + " for OP_REQUEST_INSTALL_PACKAGES found for uid " + mOriginatingUid);
                finish();
                break;

解析:
    也就是对话框为安装器弹。
可通过ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage)分析具体流程。

框架

graph TD
A[需要安装的apk] --> B[PackageInstaller/adb shell pm install]
B --> C[PackageManagerService]
C --> D[Installd]

涉及知识点

ParallelPackageParser涉及的点:
入手分析点:
parallelPackageParser.submit(file, parseFlags);
parallelPackageParser.take();

BlockingQueue队列
ExecutorService线程池

参考学习

https://blog.csdn.net/yiranfeng/article/details/103941371
https://blog.csdn.net/freekiteyu/article/details/82774947

相关文章

网友评论

      本文标题:Android之PackageManagerService ap

      本文链接:https://www.haomeiwen.com/subject/alrxrrtx.html