OTA升级成功启动系统后,提示“恭喜你!你的设备已经成功升级到......”原理

为什么系统升级完后第一次启动,弹出升级成功的对话框:

这是什么原理?系统怎么知道系统更升级完了?下次启动为什么不会提示了?

 

首先用dumpsys window查下此对话框在哪个包里的,查到是:com.mediatek.systemupdate,但查不到activity(因为不是activity)。

com.mediatek.systemupdate位于vendor/mediatek/proprietary/packages/apps/SystemUpdate应用里。

然后,再在点击上面确定时查找logcat log,找到一个疑似的service:

vendor/mediatek/proprietary/packages/apps/SystemUpdate/src/com/mediatek/systemupdate/ForegroundDialogService.java

到此service里找一些代码,通过字面意思,在vendor/mediatek/proprietary/packages/apps/SystemUpdate/res/values-zh-rCN/strings.xml里面找到相应的字符串:

<string name="app_name">系统升级</string>

    <string name="updateSuccess" product="default">恭喜您!您的手机已经成功升级到

        <xliff:g id="version" example="gb.p37">%s</xliff:g>。

</string>

由此,推出了系统在OTA升级完后第一次启动,是如何弹出升级提示的:

SystemUpdateReceiver.java //此receiver被注册,接收ACTION_BOOT_COMPLETED消息

    onReceive

      else if (action.equalsIgnoreCase(Util.Action.ACTION_BOOT_COMPLETED)//收到消息

         if (getUpdateStatus()) { //关键:这里获得升级状态

          Util.setAlarm(context, AlarmManager.RTC, //设置alarm延时提示升级报告
Calendar.getInstance().getTimeInMillis()

                        + SHOW_RESULT_TIME_DELAY,

                        Util.Action.ACTION_UPDATE_REPORT);

         }

      else if (action.equalsIgnoreCase(Util.Action.ACTION_UPDATE_REPORT)) {//收到提示

        startReportActivity();//startService:ForegroundDialogService

            resetUpdateResult();//并复位升级标志,这样下次启动不会提示

                agent.clearUpdateResult()  //通过agent清除升级标志

        send com.mediatek.systemupdate.UPDATE_SUCCESSFUL

           startService:ForegroundDialogService

 

ForegroundDialogService.java

   onStartCommand //上面调用startService后,这里被调用

      else if (dlgId == DIALOG_UPDATE_RESULT) {

        showForeGroundDlg(dlgId); //显示升级结果对话框,id为DIALOG_UPDATE_RESULT

           message = SystemProperties.get("ro.mediatek.version.release");//升级版本是

//从这获取

private boolean getUpdateStatus() {

updated = getUpdateResult();

}

 

boolean getUpdateResult() { //获取升级结果

if (Util.isEmmcSupport()) { //获取属性ro.mtk_emmc_support,这里为1

            try {

                IBinder binder = ServiceManager.getService("GoogleOtaBinder");

                SystemUpdateBinder agent = SystemUpdateBinder.Stub.asInterface(binder);

                if (agent == null) {

                    Log.e("@M_" + TAG, "Agent is null.");

                    return false;

                }

                return agent.readUpgradeResult();//调用agen来读升级结果

 

            } catch (RemoteException e) {

 

                e.printStackTrace();

                return false;

            }

        }

}    

agent的实现:vendor/mediatek/proprietary/external/GoogleOtaBinder/googleota_binder.cpp

int GoogleOtaAgent::readUpgradeResult()

{

rec = fs_mgr_get_entry_for_mount_point(fstab, "/misc");

asprintf(&source, "%s", rec->blk_device);

strcpy(dev_name, source);

dev = open(dev_name, O_RDONLY); //打开/misc设备,seek到OTA_RESULT_OFFSET读取

if (lseek(dev, OTA_RESULT_OFFSET, SEEK_SET) == -1)

count = read(dev, &result, sizeof(result));

if (close(dev) != 0)

}

#define OTA_RESULT_OFFSET    (2560)

 

到这里,大概知道,ota升级的结果是放在/misc分区的偏移OTA_RESULT_OFFSET下。

 

那么,就猜测,recovery代码里,也是在这个地方写了个标志?

在recovery代码里,搜索“2560”,果然找到:

bootable\recovery\mt_bootloader.h

#define OTA_RESULT_OFFSET    (2560)

 

一步步往回找,终于知道recovery里写这个标志的流程:

main(int argc, char **argv) {

mt_main_update_package(status, update_package, &should_wipe_cache);//安装update.zip

mt_main_write_result(status, update_package);//写升级结果

}

 

const char *MOTA_RESULT_FILE = "/data/data/com.mediatek.systemupdate/files/updateResult";

 

mt_main_write_result

  write_result_file(MOTA_RESULT_FILE, status);

    if (INSTALL_SUCCESS == result) {

        set_ota_result(1); //成功写1

    } else {

        set_ota_result(0); //失败写0

}

 

int set_ota_result(int result) {

Volume *v = volume_for_path("/misc");

if (strcmp(v->fs_type, "emmc") == 0) {

LOGE("open %s to set ota result\n", v->blk_device); //add test

         dev = open(v->blk_device, O_WRONLY | O_SYNC);

if (lseek(dev, OTA_RESULT_OFFSET, SEEK_SET) == -1) {

count = write(dev, &result, sizeof(result));

if (close(dev) != 0) {

 

}

}

上面LOGE打印的信息是:                                                                                                                                                  

E:open /dev/block/platform/soc/11230000.mmc/by-name/MISC to set ota result

/MISC分区就是对应设备/dev/block/platform/soc/11230000.mmc/by-name/MISC

 

于此,知道OTA升级后,保存了一个标志位于/MISC分区的偏移2560里,升级完第一次启动后,读这个位置的值,得知升级结果!并且读完后,就会复位它。下次不会提示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值