Android 8.0 dexoptレコード


ここではまずodexの最適化を行ういくつかの場所を初歩的に見て、後で詳細な過程を補充します.
一、installdの変化
まず7.0でinstalldがどのように起動したかを思い出します:installd.rc:
service installd /system/bin/installd
    class main
    socket installd stream 600 system system

ここでinstalldを起動すると同時にsocketも起動し、installd.cppにこのsocketを取得した場所がandroid_get_control_socketあります
もう時代遅れなので、他のことは言わないで、8.0でどのように起動したかを見てみましょう.installd.rc:
service installd /system/bin/installd
    class main

installdを起動するだけで、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);
    }

    IPCThreadState::self()->joinThreadPool();

    LOG(INFO) << "installd shutting down";

    return 0;
}

これを見てください.hでは以下のように定義する.
class InstalldNativeService : public BinderService<InstalldNativeService>, public os::BnInstalld

これを見てよく知っている感じがしますか?以前Native Serviceを実装したとき、私たちが定義したTestPlayServiceはこのように定義されていました.
class TestPlayService : public BinderService<TestPlayService>, public BnTestPlayService

これはinstalldとクライアントがbinderを介して通信していることを示している.
では、このサービスをサービスマネージャに追加する場所があり、start()を見続ける方法があるに違いありません.
[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;
}

明らかに、publish()という方法によって、その定義を見ることができます.
[BinderService.h]
static status_t publish(bool allowIsolated = false) {
    sp sm(defaultServiceManager());
    return sm->addService(
            String16(SERVICE::getServiceName()),
            new SERVICE(), allowIsolated);
}

では、このInstalldNativeServiceは私たちが見つけなければならないinstalldではないでしょうか.servicemanagerに追加された名前を見てみましょう.
static char const* getServiceName() { return "installd"; }

installdだ!
二、odex最適化の場所
1.初回起動またはアップグレード
SystemServerでJAvaにはmPackageManagerServicesがあります.updatePackagesIfNeeded()ここではまず流れを列挙し、具体的な手順は空いてからupdatePackagesIfNeed->performDexOptUpgrade->performDexOptTraced->performDexOptInternal->performDexOptInternalWithDependenciesLI->PackageDexOptimizerを貼り付ける.performDexOpt->performDexOptLI->dexOptPath->Installer.dexopt->InstalldNativeService.dexopt->dexopt.dexopt
2.アプリケーションのインストール:
PKMSでinstallPackageLI関数には、mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, null/* instructionSets/, false/checkProfiles */, getCompilerFilterForReason(REASON_INSTALL), getOrCreateCompilerPackageStats(pkg), mDexManager.isUsedByOtherApps(pkg.packageName));
3.IPackageManager.aidlはperformDexOptメソッドを提供しています
PKMSでは実現するところがありましたが、呼び出す場所が見つかりませんでした
4.IPackageManager.aidlはperformDexOptModeメソッドを提供しています
PKMSで実装されている場合、PackageManagerShellCommandで呼び出されます.shellコマンド呼び出しに提供されるはずです.
5.OTAアップグレード後:
SystemServerでJAvaにはOtaDexoptService.main(mSystemContext, mPackageManagerService);があります
public static OtaDexoptService main(Context context,
        PackageManagerService packageManagerService) {
    OtaDexoptService ota = new OtaDexoptService(context, packageManagerService);
    ServiceManager.addService("otadexopt", ota);

    // Now it's time to check whether we need to move any A/B artifacts.
    ota.moveAbArtifacts(packageManagerService.mInstaller);

    return ota;
}
private void moveAbArtifacts(Installer installer) {
    if (mDexoptCommands != null) {
        throw new IllegalStateException("Should not be ota-dexopting when trying to move.");
    }
    //         , return 
    if (!mPackageManagerService.isUpgrade()) {
        Slog.d(TAG, "No upgrade, skipping A/B artifacts check.");
        return;
    }

        installer.moveAb(path, dexCodeInstructionSet, oatDir);
}

moveAbArtifacts関数の論理:1.アップグレードするかどうかを判断する.スキャンしたパッケージにコードがあるかどうかを判断し、ない場合はスキップする.packageのcodeパスが空かどうかを判断し、空であればスキップ4.パッケージのコードがsystemまたはvendorディレクトリの下にある場合は、5をスキップします.上記条件を満たす、Installerを呼び出す.JAvaのmoveAbメソッドは最終的にdexoptを呼び出す.cppのmove_abメソッド
OtaDexoptServiceはshellコマンドにもいくつかのメソッドを呼び出します
6.システムが空いている場合:
BackgroundDexOptServiceによって実現され、BackgroundDexOptServiceはJobServiceを継承するここで2つのタスク1を開始した.起動時にodex最適化JOB_を実行POST_BOOT_UPDATE実行条件:起動1分以内2.システム休止時に最適化JOB_を実行IDLE_OPTIMIZE実行条件:設備が空き、充電器を挿入し、1分または1日おきに検査する(debugスイッチ制御による)