package com.rockchip.alexa.jacky.utils;
|
|
import android.content.Context;
|
import android.os.Environment;
|
import android.util.Log;
|
import android.util.SparseArray;
|
|
import java.io.File;
|
import java.text.SimpleDateFormat;
|
import java.util.ArrayList;
|
import java.util.Date;
|
|
|
/**
|
* Created by cjs on 2017/5/8.
|
*/
|
|
public class UpdateManager{
|
private static final String TAG = "RK_Alexa";
|
|
public static String FIRMWARE_PATH;
|
public static String UNZIP_FIRMWARE_PATH;
|
public static String FIRMWARE_NAME = "firmware.zip";
|
|
/**
|
* the key of sharePreference about firmware download
|
*/
|
public static final String KEY_DOWNLOAD_STATE = "download_state";
|
public static final String KEY_DOWNLOADING_VERSION_STR = "download_version_str";
|
public static final String KEY_DEVICE_VERSION_STR = "device_version_str";
|
public static final String KEY_DOWNLOAD_FIRMWARE_LENGTH = "download_firmware_length";
|
public static final String KEY_DOWNLOAD_UPDATE_ID = "download_update_id";
|
public static final String KEY_DOWNLOAD_UPDATE_ID_TIME = "download_update_id_time";
|
|
/**
|
* download state that will saved in sharePreference
|
*/
|
public static final int DOWNLOAD_STATE_NONE = 0;
|
public static final int DOWNLOAD_STATE_DOWNLOADING = 1;
|
public static final int DOWNLOAD_STATE_DOWNLOADED = 2;
|
public static final int DOWNLOAD_STATE_DATA_PREPARED = 3;
|
|
/**
|
* the key of five images
|
*/
|
public static final int KEY_IMG_ROOTFS = 0;
|
public static final int KEY_IMG_DATA = 1;
|
public static final int KEY_IMG_UBOOT = 2;
|
public static final int KEY_IMG_KERNEL = 3;
|
public static final int KEY_IMG_RESOURCE = 4;
|
|
/**
|
* Image name of firmware
|
*/
|
public static final String IMG_NAME_UBOOT = "uboot.img";
|
public static final String IMG_NAME_RESOURCE = "resource.img";
|
public static final String IMG_NAME_KERNEL = "kernel.img";
|
public static final String IMG_NAME_ROOTFS = "rootfs.img";
|
public static final String IMG_NAME_DATA = "data.img";
|
|
private Context mContext;
|
|
private String serverVersionNumber;
|
private String serverUpdateInfo;
|
|
private String deviceVersionNumber;
|
|
private static SparseArray<Double> serverImgVersionNumbers;
|
private static SparseArray<Double> deviceImgVersionNumbers;
|
|
public UpdateManager(Context context){
|
mContext = context;
|
Log.d(TAG, "UpdateManager: setExternalStorageDirectory");
|
FIRMWARE_PATH = Environment.getExternalStorageDirectory() + File.separator + "RK_Alexa/";
|
UNZIP_FIRMWARE_PATH = Environment.getExternalStorageDirectory() + File.separator +"RK_Alexa/firmware/";
|
|
serverImgVersionNumbers = new SparseArray<>();
|
deviceImgVersionNumbers = new SparseArray<>();
|
deviceVersionNumber = SharedPreference.getString(context,KEY_DEVICE_VERSION_STR,null);
|
if(deviceVersionNumber != null){
|
parseDeviceVersionNumber(deviceVersionNumber);
|
Log.d(TAG, "get device number version info: " + deviceVersionNumber);
|
}else{
|
Log.d(TAG, "device number version info is not available.");
|
}
|
}
|
|
/**
|
* when the versionInfo result back form httpClient.
|
* 1. save the needed params.
|
* 2. compare the info between server and device
|
* @param versionInfo
|
*/
|
public void handlerServerString(String versionInfo){
|
/* the back result from server contains version number and update information like(next line):
|
uboot.img:1.0,resource.img:1.0,kernel.img:1.0,rootfs.img:1.0,data.img:0.13 & updateInfo
|
---divided by '&' between version number and update info
|
and in version info it divided by ',' between image version info */
|
String versionNumber = versionInfo.split("&")[0];
|
String updateInfo = versionInfo.split("&")[1];
|
Log.d(TAG, "get server versionNumber info: " + versionNumber);
|
|
this.serverVersionNumber = versionNumber;
|
this.serverUpdateInfo = updateInfo;
|
parseServerVersionNumber(serverVersionNumber);
|
}
|
|
/**
|
* compare five images version number between server firmware versionNumber
|
* and device firmware versionNumber.
|
* @return isUpgradeable
|
*/
|
public boolean isUpdatable(){
|
if(deviceImgVersionNumbers.size() == 0){
|
Log.d(TAG, "Device version string don't set,update");
|
return true;
|
}
|
if(serverImgVersionNumbers.size() < 5 || deviceImgVersionNumbers.size() < 5){
|
Log.d(TAG, "global application has wrong number of image version saved");
|
return true;
|
}
|
boolean result = false;
|
if(serverImgVersionNumbers.get(KEY_IMG_ROOTFS).compareTo(deviceImgVersionNumbers.get(KEY_IMG_ROOTFS)) != 0){
|
result = true;
|
}
|
if(serverImgVersionNumbers.get(KEY_IMG_DATA).compareTo(deviceImgVersionNumbers.get(KEY_IMG_DATA)) != 0){
|
result = true;
|
}
|
if(serverImgVersionNumbers.get(KEY_IMG_UBOOT).compareTo(deviceImgVersionNumbers.get(KEY_IMG_UBOOT)) != 0) {
|
result = true;
|
}
|
if(serverImgVersionNumbers.get(KEY_IMG_KERNEL).compareTo(deviceImgVersionNumbers.get(KEY_IMG_KERNEL)) != 0){
|
result = true;
|
}
|
if(serverImgVersionNumbers.get(KEY_IMG_RESOURCE).compareTo(deviceImgVersionNumbers.get(KEY_IMG_RESOURCE)) != 0){
|
result = true;
|
}
|
return result;
|
}
|
|
/**
|
* save server versionNumber string into ArrayList info
|
* @param versionNumber
|
*/
|
public static void parseServerVersionNumber(String versionNumber){
|
/* the backed string get 5 images version number like:
|
uboot.img:1.0,resource.img:1.0,kernel.img:1.0,rootfs.img:1.0,data.img:0.13 */
|
String[] imgVersionNumbers = versionNumber.split(",");
|
|
for(int i = 0;i < imgVersionNumbers.length; i++){
|
String imgName = imgVersionNumbers[i].split(":")[0];
|
double imgVersionNumber;
|
if(imgName.contains(IMG_NAME_UBOOT)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "server uboot: " + imgVersionNumber);
|
serverImgVersionNumbers.put(KEY_IMG_UBOOT,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_RESOURCE)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "server resource: " + imgVersionNumber);
|
serverImgVersionNumbers.put(KEY_IMG_RESOURCE,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_KERNEL)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "server kernel: " + imgVersionNumber);
|
serverImgVersionNumbers.put(KEY_IMG_KERNEL,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_ROOTFS)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "server rootfs: " + imgVersionNumber);
|
serverImgVersionNumbers.put(KEY_IMG_ROOTFS,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_DATA)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "server data: " + imgVersionNumber);
|
serverImgVersionNumbers.put(KEY_IMG_DATA,imgVersionNumber);
|
}
|
}
|
}
|
|
/**
|
* save device versionNumber string into ArrayList info
|
* @param versionNumber
|
*/
|
public static void parseDeviceVersionNumber(String versionNumber){
|
/* the backed string get 5 images version number like:
|
uboot.img:1.0,resource.img:1.0,kernel.img:1.0,rootfs.img:1.0,data.img:0.13 */
|
String[] imgVersionNumbers = versionNumber.split(",");
|
|
for(int i = 0;i < imgVersionNumbers.length; i++){
|
String imgName = imgVersionNumbers[i].split(":")[0];
|
double imgVersionNumber;
|
if(imgName.contains(IMG_NAME_UBOOT)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "device uboot: " + imgVersionNumber + " server uboot" + serverImgVersionNumbers.get(KEY_IMG_UBOOT));
|
deviceImgVersionNumbers.put(KEY_IMG_UBOOT,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_RESOURCE)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "device resource: " + imgVersionNumber + " server RESOURCE" + serverImgVersionNumbers.get(KEY_IMG_RESOURCE));
|
deviceImgVersionNumbers.put(KEY_IMG_RESOURCE,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_KERNEL)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "device kernel: " + imgVersionNumber + " server kernel" + serverImgVersionNumbers.get(KEY_IMG_KERNEL));
|
deviceImgVersionNumbers.put(KEY_IMG_KERNEL,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_ROOTFS)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "device rootfs: " + imgVersionNumber + " server rootfs" + serverImgVersionNumbers.get(KEY_IMG_ROOTFS));
|
deviceImgVersionNumbers.put(KEY_IMG_ROOTFS,imgVersionNumber);
|
}else if(imgName.contains(IMG_NAME_DATA)){
|
imgVersionNumber = Double.parseDouble(imgVersionNumbers[i].split(":")[1]);
|
Log.d(TAG, "device data: " + imgVersionNumber + " server data" + serverImgVersionNumbers.get(KEY_IMG_DATA));
|
deviceImgVersionNumbers.put(KEY_IMG_DATA,imgVersionNumber);
|
}
|
}
|
}
|
|
public static short getUpdateImageBit(String versionNumberStr){
|
// save versionNumber string to SharePreference
|
Log.d(TAG, "getUpdateImageBit: " + versionNumberStr);
|
SharedPreference.putString(UpdateManager.KEY_DEVICE_VERSION_STR,versionNumberStr);
|
|
UpdateManager.parseDeviceVersionNumber(versionNumberStr);
|
|
int imgBit = 0x0000;
|
int img_uboot_on = 0x0001,img_resource_on = 0x0002,img_kernel_on = 0x0004;
|
int img_rootfs_on = 0x0008,img_data_on = 0x0010;
|
|
if(deviceImgVersionNumbers.get(KEY_IMG_UBOOT).compareTo(serverImgVersionNumbers.get(KEY_IMG_UBOOT)) != 0) {
|
imgBit = imgBit | img_uboot_on;
|
}
|
if(deviceImgVersionNumbers.get(KEY_IMG_RESOURCE).compareTo(serverImgVersionNumbers.get(KEY_IMG_RESOURCE)) != 0){
|
imgBit = imgBit | img_resource_on;
|
}
|
if(deviceImgVersionNumbers.get(KEY_IMG_KERNEL).compareTo(serverImgVersionNumbers.get(KEY_IMG_KERNEL)) != 0){
|
imgBit = imgBit | img_kernel_on;
|
}
|
if(deviceImgVersionNumbers.get(KEY_IMG_ROOTFS).compareTo(serverImgVersionNumbers.get(KEY_IMG_ROOTFS)) != 0){
|
imgBit = imgBit | img_rootfs_on;
|
}
|
if(deviceImgVersionNumbers.get(KEY_IMG_DATA).compareTo(serverImgVersionNumbers.get(KEY_IMG_DATA)) != 0){
|
imgBit = imgBit | img_data_on;
|
}
|
return (short)imgBit;
|
}
|
|
/**
|
* get update version string and put back to jni.
|
* this method also used as a call-back when device update success
|
* @return
|
*/
|
public static String getUpdateVersionStr(){
|
deviceImgVersionNumbers.put(KEY_IMG_ROOTFS,serverImgVersionNumbers.get(KEY_IMG_ROOTFS));
|
deviceImgVersionNumbers.put(KEY_IMG_DATA,serverImgVersionNumbers.get(KEY_IMG_DATA));
|
deviceImgVersionNumbers.put(KEY_IMG_UBOOT,serverImgVersionNumbers.get(KEY_IMG_UBOOT));
|
deviceImgVersionNumbers.put(KEY_IMG_KERNEL,serverImgVersionNumbers.get(KEY_IMG_KERNEL));
|
deviceImgVersionNumbers.put(KEY_IMG_RESOURCE,serverImgVersionNumbers.get(KEY_IMG_RESOURCE));
|
|
StringBuffer sb = new StringBuffer();
|
sb.append("uboot.img:").append(deviceImgVersionNumbers.get(KEY_IMG_UBOOT)).append(",");
|
sb.append("resource.img:").append(deviceImgVersionNumbers.get(KEY_IMG_RESOURCE)).append(",");
|
sb.append("kernel.img:").append(deviceImgVersionNumbers.get(KEY_IMG_KERNEL)).append(",");
|
sb.append("rootfs.img:").append(deviceImgVersionNumbers.get(KEY_IMG_ROOTFS)).append(",");
|
sb.append("data.img:").append(deviceImgVersionNumbers.get(KEY_IMG_DATA)).append(",");
|
Log.d(TAG, "new Updated versionNumber string: " + sb.toString());
|
return sb.toString();
|
}
|
|
/**
|
* it is used to check download state error
|
* when app quit while downloading or delete fle
|
*/
|
public void reInitDownloadStateByCurrent(){
|
int currentDownloadState = SharedPreference.getInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_NONE);
|
String downloadVersionStr = SharedPreference.getString(KEY_DOWNLOADING_VERSION_STR,null);
|
int hasDownloadLength = FileUtil.getFileSize(FIRMWARE_PATH + FIRMWARE_NAME);
|
switch (currentDownloadState){
|
case DOWNLOAD_STATE_DOWNLOADED:
|
if(downloadVersionStr == null || !downloadVersionStr.equals(serverVersionNumber)){
|
SharedPreference.putInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_NONE);
|
}
|
break;
|
case DOWNLOAD_STATE_DOWNLOADING:
|
/* it means that firmware has download finished */
|
if(hasDownloadLength == SharedPreference.getInt(mContext,KEY_DOWNLOAD_FIRMWARE_LENGTH,-1)){
|
SharedPreference.putInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_DOWNLOADED);
|
}
|
break;
|
case DOWNLOAD_STATE_NONE:
|
break;
|
case DOWNLOAD_STATE_DATA_PREPARED:
|
if(downloadVersionStr == null || !downloadVersionStr.equals(serverVersionNumber)){
|
SharedPreference.putInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_NONE);
|
}else if(!isImgDataReady()){
|
SharedPreference.putInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_DOWNLOADED);
|
}
|
break;
|
default:
|
break;
|
}
|
|
if(hasDownloadLength == 0 && !isImgDataReady()){
|
SharedPreference.putInt(mContext,KEY_DOWNLOAD_STATE,DOWNLOAD_STATE_NONE);
|
}
|
}
|
|
public static boolean isImgDataReady(){
|
ArrayList<Integer> imgNeedUpdate = new ArrayList<>();
|
imgNeedUpdate.add(KEY_IMG_DATA);
|
imgNeedUpdate.add(KEY_IMG_KERNEL);
|
imgNeedUpdate.add(KEY_IMG_RESOURCE);
|
imgNeedUpdate.add(KEY_IMG_ROOTFS);
|
imgNeedUpdate.add(KEY_IMG_UBOOT);
|
for(int i = 0; i < imgNeedUpdate.size(); i++ ){
|
File tempFile;
|
switch (imgNeedUpdate.get(i)){
|
case KEY_IMG_UBOOT:
|
tempFile = new File(UNZIP_FIRMWARE_PATH + IMG_NAME_UBOOT);
|
if(!tempFile.exists()){
|
return false;
|
}
|
break;
|
case KEY_IMG_RESOURCE:
|
tempFile = new File(UNZIP_FIRMWARE_PATH + IMG_NAME_RESOURCE);
|
if(!tempFile.exists()){
|
return false;
|
}
|
break;
|
case KEY_IMG_KERNEL:
|
tempFile = new File(UNZIP_FIRMWARE_PATH + IMG_NAME_KERNEL);
|
if(!tempFile.exists()){
|
return false;
|
}
|
break;
|
case KEY_IMG_ROOTFS:
|
tempFile = new File(UNZIP_FIRMWARE_PATH + IMG_NAME_ROOTFS);
|
if(!tempFile.exists()){
|
return false;
|
}
|
break;
|
case KEY_IMG_DATA:
|
tempFile = new File(UNZIP_FIRMWARE_PATH + IMG_NAME_DATA);
|
if(!tempFile.exists()){
|
return false;
|
}
|
break;
|
}
|
}
|
return true;
|
}
|
|
public boolean isFirmwareReady(){
|
return FileUtil.isFileExit(FIRMWARE_PATH + FIRMWARE_NAME);
|
}
|
|
/**
|
* this method produce updateId used for tcp connection with device.
|
* if the updateId is not same with device,reConnection and transfer.
|
* @return updateId
|
*/
|
public long resetUpdateId(){
|
/* produce a time correlation long value for update id*/
|
return updater_client.getNewUpdateId();
|
}
|
|
public String getServerVersionUpdateInfo(){
|
return serverUpdateInfo;
|
}
|
|
public String getServerVersionNumberStr(){
|
return serverVersionNumber;
|
}
|
|
public void initPathFileBeforeDownload(){
|
File tempFile = new File(FIRMWARE_PATH);
|
if(!tempFile.exists()){
|
tempFile.mkdir();
|
}
|
File tempFile2 = new File(FIRMWARE_PATH + FIRMWARE_NAME);
|
if(tempFile2.isFile() && tempFile2.exists()){
|
tempFile2.delete();
|
}
|
}
|
|
}
|