HiSilicon アンドロイドエッセイ - ブートビデオとブートアニメーションのプロセス分析

1.ポータルを起動する

1.ブートビデオ

rc ファイル構成は Android/device/hisilicon/bigfish/etc/initrc/init.bigfish.rc にあります。

......
service bootvideo /system/bin/bootvideo
    priority -20
    class core
    user system
    group system graphics input root
    oneshot

on init
    start bootvideo
    # Set log level
    loglevel 3

    # Create cgroup mount point for memory
    mount tmpfs none /sys/fs/cgroup mode=0750,uid=0,gid=1000
    mkdir /sys/fs/cgroup/memory 0750 root system
    mount cgroup none /sys/fs/cgroup/memory memory
......

2.ブータニメーション

rc 構成は Android/frameworks/base/cmds/bootanimation/bootanim.rc にあります。

service bootanim /system/bin/bootanimation
    class core animation
    user graphics
    group graphics audio
    disabled
    oneshot
    writepid /dev/stune/top-app/tasks

ここの rc ファイルは Android/frameworks/base/cmds/bootanimation/Android.mk にあります。

......
LOCAL_INIT_RC := bootanim.rc
......

/system/etc/init ディレクトリにコンパイルされ、Android/system/core/init/init.cpp の LoadBootScripts によって解析されます。

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

したがって、ここから、bootanimation よりも bootvideo サービスが早く開始されることがわかります。

二. bootvideo

コードは Android/device/hisilicon/bigfish/frameworks/hibootvideo にあり、次の構造になっています。

メイン関数の入り口は src/bootvideo_main.cpp にあります。ここでは、最初に prop.service.bootop.type 属性が bootvideo と等しいかどうかを判断します。そうでない場合は、bootvideo を直接終了します。そうでない場合は、HI_StartPlayBootvideo に入ります。

int main(int argc, char **argv)
{
    int count = 0;
    const int waitPropCount = 100; // try to wait prop service 1 sec
    const int waitPropDelay = 10000; // 10ms
    char bootop[PROPERTY_VALUE_MAX] = {0};
    while (!property_get("prop.service.bootop.type", bootop, nullptr)) {
        // bootvideo starts at on init process, property may not load ready,
        // try to wait a while...
        count++;
        if (count >= waitPropCount) {
            break;
        }
        usleep(waitPropDelay);
    }
    if (strncmp(bootop, "bootvideo", strlen("bootvideo"))) {
        return 0;
    }

    ALOGD("bootvideo START!");
    HI_StartPlayBootvideo();

    return 0;
}

HiSilicon のコード構造は非常に明確なので、ここでは詳しく説明しませんが、コードを持っている学生なら自分で非常に明確に理解できるでしょう。

bootvideo のおおよそのプロセスは次のとおりです。

HI_BootvideoInit --> HI_InitBootVideoPlayer --> HI_BootPlayVideo --> HiBootvideoUI --> HI_CheckIfExitPlay

三.ブートアニメーション

コードは Android/frameworks/base/cmds/bootanimation にあり、次の構造になっています。

 メイン関数エントリは bootanimation_main.cpp にあります。ここで、HiSilicon は最初に prop.service.bootop.type 属性が bootanim と等しいかどうかを判断します。そうでない場合は、bootanimation を直接終了します。それ以外の場合は、BootAnimation スレッドを作成します

int main()
{
    //HISILICON add begin
    //support bootvide||quickplay||bootanimation
    char bootop[PROPERTY_VALUE_MAX];
    property_get("prop.service.bootop.type", bootop, "bootanim");
    if(strncmp(bootop, "bootanim", 8) != 0) {
        ALOGV("bootop %s enabled", bootop);
        return 0;
    }
    //HISILICON add end

    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

    bool noBootAnimation = bootAnimationDisabled();
    ALOGI_IF(noBootAnimation,  "boot animation disabled");
    if (!noBootAnimation) {

        sp<ProcessState> proc(ProcessState::self());
        ProcessState::self()->startThreadPool();

        waitForSurfaceFlinger();

        // create the boot animation object
        sp<BootAnimation> boot = new BootAnimation(new AudioAnimationCallbacks());
        ALOGV("Boot animation set up. Joining pool.");

        IPCThreadState::self()->joinThreadPool();
    }
    ALOGV("Boot animation exit");
    return 0;
}

フレームワークのスレッド、それは while ループです。

スレッドが作成されると、スレッド自体が一度 sp と wp になります。

初めて実行する場合はスレッドのreadyToRun()メソッドが実行された後、threadLoop()が実行され、それ以外の場合は直接threadLoop()が実行されます。

threadLoop() メソッドには戻り値があり、threadLoop() が false を返した場合、スレッドはクリーンアップ作業を実行し、while ループを終了して操作を終了します。

ネイティブ ブートアニメーションは、まず、対応するパスにブート アニメーション zip ファイルが存在するかどうかを判断し、存在しない場合は、android() 画像表示プロセスを実行します。

bool BootAnimation::android()
{
    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
            elapsedRealtime());
    initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
    initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");

    mCallbacks->init({});

    // clear screen
......

zip ファイルが存在する場合は、movie() の圧縮 zip 表示処理に従います。

bool BootAnimation::movie()
{
    Animation* animation = loadAnimation(mZipFileName);
    if (animation == NULL)
        return false;
......

4.デバッグ

1. 上記の分析によると、マシンの bootanitiom または bootvideo を直接デバッグしたい場合は、prop.service.bootop.type 属性を変更できます。このプロパティはマシンの /vendor/build.prop にあり、変更して再起動すると有効になります。

2. リソースは、bootanitiom または bootvideo に対応するファイル パスに保存する必要があります。

bootanimation のデフォルトのパスは、ro.prop.bootanim.path=/atv/bootvideo/bootanimation.zip の値を読み取ります。

......
    char customBootanimationFile[PROPERTY_VALUE_MAX];
    property_get("ro.prop.bootanim.path", customBootanimationFile, "");

    bool encryptedAnimation = atoi(decrypt) != 0 ||
        !strcmp("trigger_restart_min_framework", decrypt);

    if (!mShuttingDown && encryptedAnimation) {
        static const char* encryptedBootFiles[] =
            {PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE};
        for (const char* f : encryptedBootFiles) {
            if (access(f, R_OK) == 0) {
                mZipFileName = f;
                return NO_ERROR;
            }
        }
    }
    static const char* bootFiles[] =
        {customBootanimationFile, PRODUCT_BOOTANIMATION_FILE, OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
    static const char* shutdownFiles[] =
        {"/atv/bootvideo/shutdownanimation.zip", PRODUCT_SHUTDOWNANIMATION_FILE, OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};

    for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
        if (access(f, R_OK) == 0) {
            mZipFileName = f;
            return NO_ERROR;
        }
    }
......

bootvideo パスは system/etc/config.xml を通じて構成されます。

HI_BootvideoGetPath --> HiBootvideoConfiger::GetFeature --> HiBootvideoConfiger::GetPropertyValue --> XML ファイルの path1 および path2 パスを解析します。

<?xml version='1.0'?>
<config>
  <bootvideo>
    <property key="path1" value="/vendor/media/bootvideo.mp4"/>
    <property key="path2" value="/data/local/data/bootvideosnd.mp4"/>
    <property key="strPath1" value="/data/local/data/strbootvideo.mp4"/>
    <property key="strPath2" value="/data/local/data/strbootvideosnd.mp4"/>
    <property key="isEnableInput" enable="true"/>
    <property key="isEnableUI" enable="true">
      <property key="isEnableCountDown" enable="false" language="en"/>
      <property key="isEnableVolumeBar" enable="true"/>
      <property key="isEnableVolumeMute" enable="true"/>
    </property>
  </bootvideo>
</config>

おすすめ

転載: blog.csdn.net/hmz0303hf/article/details/125481382