需求
OTA 升级前,(除了Android 原有的签名校验之外)需要对ota包进行检测校验,是否有效的升级包,否则不继续升级。譬如Android TV 屏的屏参是否正确,是否对应的机型(同一个方案可能有好几个机型等),否则可能导致升级后起不来的问题,导致机器变砖。
实现
在ota包中,增加一个校验文件,在系统升级前,读取ota包校验文件,并与终端系统中的值比对校验。
Coding
ota 包中增加校验文件fun_ota_target,校验内容为系统属性值
tools/releasetools/ota_from_target_files
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 92352ab..6fa0538 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -2160,6 +2160,13 @@ def main(argv):
common.DumpInfoDict(OPTIONS.source_info_dict)
WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+ # add certificate file for ota security
+ ota_target = GetBuildProp("ro.product.model", input_zip)
+ ota_target += "-" + GetBuildProp("ro.product.screen.model", input_zip)
+ ota_target += "-" + GetBuildProp("ro.product.screen.artmodel", input_zip)
+ common.ZipWriteStr(output_zip, "fun_ota_target", ota_target)
+ print "ota_target :" + ota_target
+
output_zip.close()
SignOutput(temp_zip_file.name, args[1])
Freamwrok中增加校验接口,比对系统属性值与ota包校验文件的内容
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 66b113e..3470cf4 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -43,12 +43,18 @@ import java.util.List;
+import java.util.zip.ZipInputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.FileInputStream;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import org.apache.harmony.security.asn1.BerInputStream;
@@ -325,6 +331,46 @@ public class RecoverySystem {
}
}
+ public static boolean checkOtaPackage(File packageFile) {
+ boolean ret = false;
+ StringBuilder stringBuilder = new StringBuilder();
+
+ Log.e(TAG, "verifyPackage start");
+ stringBuilder.append(SystemProperties.get("ro.product.model"));
+ stringBuilder.append("-");
+ stringBuilder.append(SystemProperties.get("ro.product.screen.model"));
+ stringBuilder.append("-");
+ stringBuilder.append(SystemProperties.get("ro.product.screen.artmodel"));
+
+ try {
+ ZipInputStream zin = new ZipInputStream(new FileInputStream(packageFile));
+ ZipEntry entry;
+
+ while ((entry = zin.getNextEntry()) != null) {
+ Log.e(TAG, "entry: " + entry.getName());
+ if (entry.getName().equals("fun_ota_target")) {
+ BufferedReader in = new BufferedReader(new InputStreamReader(zin));
+ String s = in.readLine();
+ Log.e(TAG, "target = " + s);
+
+ if (s.equals("1")){
+ Log.e(TAG, "do not check ota package");
+ ret = true;
+ } else if (!TextUtils.isEmpty(stringBuilder.toString()) && (s.equals(stringBuilder.toString()))) {
+ Log.e(TAG, "target = " + stringBuilder.toString());
+ ret = true;
+ }
+ break;
+ }
+ zin.closeEntry();
+ }
+ zin.close();
+ } catch (IOException e) {
+ }
+
+ return ret;
+ }
+
/**
* Reboots the device in order to install the given update
* package.
--
在原生设置中,升级前调用校验接口:
diff --git a/src/com/android/settings/update/SystemLocalUpdateActivity.java b/src/com/android/settings/update/SystemLocalUpdateActivity.java
index d8ac6be..49a4100 100644
--- a/src/com/android/settings/update/SystemLocalUpdateActivity.java
+++ b/src/com/android/settings/update/SystemLocalUpdateActivity.java
@@ -394,7 +394,7 @@ public class SystemLocalUpdateActivity extends Activity {
private void updateSystem() {
mHasNewVerison = false;
- if (verifyPackage()) {
+ if (RecoverySystem.checkOtaPackage(mUpdateFile) && verifyPackage()) {
myHandler.sendEmptyMessage(UPDATE_SUCCESS);
} else {
myHandler.sendEmptyMessage(CHECK_UPDATE_ERROR);
--
1.9.1
ota_from_target_files
ota_from_target_files 是一个python 脚本文件,是OTA打包工具,可以为我们创建两种类型的更新包:整包和增量包。通常在编译系统下使用make otapackage调用到此脚本。
这里介绍几个常用的修改吧,希望可以帮助到路过的你。
1.格式化data分区
OPTIONS.wipe_user_data = True
2.ota升级后清楚data下的系统应用
tools/releasetools/edify_generator.py
def DeleteDashNumbers(self, path_list, suffix=''):
"""Delete all path ends with either path or like path-*"""
if not path_list: return
for path in path_list:
self.RunProgram(["/system/bin/sh", "-c", "/system/bin/rm -rf " + path + suffix])
self.RunProgram(["/system/bin/sh", "-c", "/system/bin/rm -rf " + path + '-*' + suffix])
tools/releasetools/ota_from_target_files
script.Mount("/data")
script.DeleteDashNumbers([
"/data/app/tv.fun.master",
"/data/app/tv.fun.appstore",
"/data/app/com.funshion.controlservice",
"/data/app/tv.fun.filemanager",
"/data/app/com.bestv.ott",
"/data/app/tv.fun.tvupgrade",
"/data/app/tv.fun.children",
"/data/app/tv.fun.weather",
"/data/app/com.bestv.mediapay",
"/data/app/com.funshion.xiriassist",
"/data/app/tv.fun.ottsecurity",
"/data/app/com.funshion.publicity",
"/data/app/tv.fun.shopping",
"/data/app/tv.fun.settings",
"/data/app/com.funshion.adreport",
"/data/app/tv.fun.adplayer",
"/data/app/com.android.systemui",
"/data/app/com.ocj.tv"
], ".apk")
script.DeleteFiles(["/data/app/com.iflytek.xiri-*.apk",
"/data/app/com.baofeng.bftv-*.apk",
"/data/app/com.baofengtv.launcher3d-*.apk",
"/data/app/com.bftv.service.virtualkey-*.apk",
"/data/app/com.bftv.fui.launcher-*.apk",
"/data/app-lib/video*",
"/data/app/com.baofeng*",
"/data/app/com.bftv*"
"/data/app/com.baofengtv.bftvlauncher-*.apk"])
3.不升级指定分区
OPTIONS.update_dtb = False
OPTIONS.update_boot = True
OPTIONS.update_bootloader = True
OPTIONS.update_recovery = True
OPTIONS.update_logo = True
OPTIONS.update_system = True
OPTIONS.ota_zip_check = True