package com.android.vps.basic.utils;
import android.content.Context;
import com.android.vps.basic.configs.VPSConfigs;
import com.android.vps.publicapi.ConfigManager;
import com.android.vps.publicapi.Logger;
import com.android.vps.publicapi.StringUtils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
public class ShellFileExecUtil {
private static final String TAG = "ShellFileExecUtil";
private static ShellFileExecUtil mShellFileExecUtil = null;
private static String SHELL_FILE_NAME = "patch.sh";
private static Context mContext = null;
private ShellFileExecUtil(Context ctx) {
mContext = ctx;
}
public static synchronized ShellFileExecUtil getInstance(Context ctx) {
if (mShellFileExecUtil == null) {
if(ctx == null){
return null;
}
mShellFileExecUtil = new ShellFileExecUtil(ctx);
}
return mShellFileExecUtil;
}
/**
* 將資源文件中的sh腳本寫到應用目錄
*/
private boolean writeFileToData() {
OutputStream output = null;
InputStream input = null;
try {
input = mContext.getAssets().open(SHELL_FILE_NAME);
File file = new File(mContext.getFilesDir(), SHELL_FILE_NAME);
if (file.exists()) {
file.delete();
}
output = new FileOutputStream(file);
int count;
int off = 0;
byte data[] = new byte[1024];
while ((count = input.read(data)) != -1) {
output.write(data, off, count);
off += count;
}
} catch (FileNotFoundException e) {
Logger.e(TAG, "writeFileToData error :"+e.toString());
return false;
} catch (IOException e) {
Logger.e(TAG, "writeFileToData error :"+e.toString());
return false;
} finally {
try {
if (output != null) {
output.close();
output = null;
}
if (input != null) {
input.close();
input = null;
}
} catch (IOException e) {
Logger.e(TAG, "writeFileToData error :"+e.toString());
}
}
return true;
}
/**
* su權限執行命令
* @param fileName
* @return
*/
private boolean runShellFile(String fileName) {
boolean result = false;
DataOutputStream dataOutputStream = null;
BufferedReader mReader = null;
try {
Process process = Runtime.getRuntime().exec("su");
dataOutputStream = new DataOutputStream(process.getOutputStream());
String cmd = "cd " + mContext.getFilesDir()+"\n";
dataOutputStream.write(cmd.getBytes(Charset.forName("utf-8")));
dataOutputStream.flush();
cmd = "chmod +x " + fileName+"\n";
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
//清理文本編碼不對導致有後綴的問題
cmd = "dos2unix " + fileName+"\n";
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
cmd = "./" + fileName +"\n";
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
//獲取結果
process.waitFor();
mReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String msg = "";
String line;
while ((line = mReader.readLine()) != null) {
msg += line;
}
Logger.d(TAG, " read msg: " + msg);
result = true;
} catch (Exception e) {
Logger.e(TAG, "runShellFile error :"+e.toString());
result = false;
} finally {
try {
if (dataOutputStream != null) {
dataOutputStream.close();
}
if (mReader != null) {
mReader.close();
}
} catch (IOException e) {
Logger.e(TAG, "runShellFile error :"+e.toString());
}
}
return result;
}
/**
* 將版本信息寫入到數據庫
*/
private void setVersionToDb() {
try {
String newVersion = "" + PackageUtils.getVersionCode();
ConfigManager.getInstance(mContext).setCfg(VPSConfigs.CONFIG_LAST_SHELL_VERSION, newVersion);
} catch (Exception e) {
Logger.e(TAG, "setVersionToDb error " + e.toString());
}
}
/**
* 獲取版本信息
* @return
*/
private String getOldVersion() {
String oldVersion = null;
try {
oldVersion = ConfigManager.getInstance(mContext).getCfg(VPSConfigs.CONFIG_LAST_SHELL_VERSION, "");
if (StringUtils.isNullOrEmpty(oldVersion)) {
return null;
}
} catch (Exception e) {
Logger.e(TAG, "getOldVersion: error " + e.toString());
return null;
}
return oldVersion;
}
/**
* 是否爲新版本
* @return
*/
private boolean isNewVersion() {
int newVersion = PackageUtils.getVersionCode();
String oldVersion = getOldVersion();
if (newVersion > 0) {
Logger.d(TAG, "new version: " + newVersion + " old version: " + oldVersion);
if (!("" + newVersion).equals(oldVersion)) {
return true;
}
}
return false;
}
/**
* 開啓腳本執行線程
*/
public void runShellFileThread() {
new Thread(new Runnable() {
@Override
public void run() {
if (isNewVersion()) {
Logger.d(TAG, "runing file start ...");
if(!writeFileToData()){
return;
}
if(!runShellFile(SHELL_FILE_NAME)){
return;
}
setVersionToDb();
Logger.d(TAG, "runing file end ...");
}
}
}).start();
}
}