You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TermApp/mpmaster/src/main/java/com/xypower/mpmaster/AppMaster.java

505 lines
17 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.xypower.mpmaster;
import android.content.Context;
import android.os.Environment;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Base64;
import com.dev.devapi.api.SysApi;
import com.xypower.common.FileDownloader;
import com.xypower.common.FileUploader;
import com.xypower.common.InetAddressUtils;
import com.xypower.common.JSONUtils;
import com.xypower.common.MicroPhotoContext;
import com.xypower.common.ZipUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class AppMaster {
private MpMasterService mService;
private String mMasterUrl;
private String mCmdid;
private PowerManager.WakeLock mWakelock;
public static final String CMD_REBOOT_APP = "cmd_reboot_app";
public static final String CMD_REBOOT_MASTER = "cmd_reboot_mpmaster";
public static final String CMD_REBOOT_DEV = "yw_cmd_android_reboot";
public static final String CMD_UPGRADE = "upgrade";
public static final String CMD_UPLOAD_LOGS = "yw_cmd_upload_i1_zip_log";
public static final String CMD_SET_CMA = "i1_cmd_set_i1_server_ip_port";
public static final String CMD_SET_MNTN = "i1_cmd_set_xy_yw_ip_port";
public static final String CMD_SET_APP_HB = "i1_cmd_set_i1_heart_beat_time";
public static final String CMD_UPDATE_CONFIG = "upd_cfg";
public static final String CMD_PULL_FILE = "pull_files";
public static final String CMD_PUSH_FILE = "push_file";
public static final String CMD_HOT_SPOT = "yw_cmd_hot_spot";
public static final String CMD_ENABLE_GPS = "yw_cmd_enable_gps";
public static final String CMD_ENABLE_OTG = "yw_cmd_enable_otg";
public AppMaster(MpMasterService service, String masterUrl, String cmdid) {
mService = service;
mMasterUrl = masterUrl;
mCmdid = cmdid;
mWakelock = null;
try {
PowerManager powerManager = (PowerManager) service.getSystemService(Context.POWER_SERVICE);
mWakelock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "com.xypower.mpmaster:MpMaster");
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
protected void finalize() {
try {
if (mWakelock != null) {
mWakelock.setReferenceCounted(false);
mWakelock.release();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
mWakelock = null;
}
mService = null;
}
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
String masterUrl = mMasterUrl;
if (TextUtils.isEmpty(masterUrl)) {
return;
}
HttpURLConnection httpURLConnection = null;
InputStream inputStream = null;
try {
if (masterUrl.indexOf('?') != -1) {
masterUrl += "&" + MicroPhotoContext.MASTER_URL_CMDID + "=" + URLEncoder.encode(mCmdid, "UTF-8");
} else {
masterUrl += "?" + MicroPhotoContext.MASTER_URL_CMDID + "=" + URLEncoder.encode(mCmdid, "UTF-8");
}
URL url = new URL(masterUrl);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(15000);
httpURLConnection.setReadTimeout(15000);
httpURLConnection.setRequestMethod("POST");
// httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestProperty("Accept-Cmds", "Multiple");
List<Pair<String, String>> postParams = new ArrayList<>();
postParams.add(new Pair<String, String>("id", mCmdid));
postParams.add(new Pair<String, String>("i1Version", mService.getMpAppVersion()));
postParams.add(new Pair<String, String>("maintainVersion", mService.getMasterAppVersion()));
// postParams(httpURLConnection.getOutputStream(), postParams);
buildParams(httpURLConnection.getOutputStream());
httpURLConnection.connect();
inputStream = httpURLConnection.getInputStream();
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
//在子线程中不能操作UI线程通过handler在UI线程中进行操作
// handler.sendEmptyMessage(0x00);
String response = convertStreamToString(inputStream);
process(response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private void process(String content) {
if (TextUtils.isEmpty(content)) {
return;
}
try {
JSONObject jsonObject = new JSONObject(content);
int isUpgrade = jsonObject.optInt("isUpgrade", 0);
String url = jsonObject.optString("url", null);
int mntnMode = jsonObject.optInt("yw", 0);
int quickHbMode = jsonObject.optInt("kxt", 0);
mService.setMntnMode(mntnMode != 0, quickHbMode != 0);
if (isUpgrade == 1 && !TextUtils.isEmpty(url)) {
upgradeApp(url);
}
processCmd(jsonObject);
JSONArray cmdObjects = jsonObject.optJSONArray("cmds");
if (cmdObjects != null) {
int cnt = cmdObjects.length();
for (int idx = 0; idx < cnt; idx++) {
JSONObject cmdObject = cmdObjects.getJSONObject(idx);
if (cmdObject != null) {
processCmd(cmdObject);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void processCmd(JSONObject jsonObject) {
String cmd = jsonObject.optString("cmd", "");
if (TextUtils.equals(cmd, CMD_REBOOT_DEV)) {
SysApi.reboot(mService.getApplicationContext());
} else if (TextUtils.equals(cmd, CMD_UPLOAD_LOGS)) {
String url = jsonObject.optString("url", null);
uploadLogs(url);
} else if (TextUtils.equals(cmd, CMD_SET_CMA)) {
String ip = jsonObject.optString("value_str", null);
int port = jsonObject.optInt("value_int", 0);
updateCma(ip, port);
} else if (TextUtils.equals(cmd, CMD_SET_MNTN)) {
String ip = jsonObject.optString("value_str", null);
int port = jsonObject.optInt("value_int", 0);
String newUrl = buildMntnServer(ip, port);
if (newUrl != null) {
mService.updateMntn(newUrl);
}
} else if (TextUtils.equals(cmd, CMD_UPDATE_CONFIG)) {
String path = jsonObject.optString("path", null);
String fileName = jsonObject.optString("fileName", null);
String name = jsonObject.optString("name", null);
int fieldType = jsonObject.optInt("type", 0);
JSONObject val = jsonObject.optJSONObject("value");
} else if (TextUtils.equals(cmd, CMD_PUSH_FILE)) {
String path = jsonObject.optString("path", null);
String content = jsonObject.optString("content", null);
File file = new File(path);
File parentPath = file.getParentFile();
if (!parentPath.exists()) {
parentPath.mkdirs();
}
byte[] data = null;
try {
data = Base64.decode(content, Base64.DEFAULT);
} catch (Exception ex) {
}
if (data != null) {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (Exception ex) {
}
}
}
}
} else if (TextUtils.equals(cmd, CMD_HOT_SPOT)) {
int enable = jsonObject.optInt("enable", 1);
String name = jsonObject.optString("name", "XYMP");
if (enable != 0) {
SysApi.enableApp(mService.getApplicationContext(), name);
} else {
SysApi.disableApp(mService.getApplicationContext(), name);
}
} else if (TextUtils.equals(cmd, CMD_ENABLE_GPS)) {
int enable = jsonObject.optInt("enable", 1);
SysApi.enableGps(mService.getApplicationContext(), (enable != 0));
} else if (TextUtils.equals(cmd, CMD_ENABLE_OTG)) {
int enable = jsonObject.optInt("enable", 1);
SysApi.setOtgState((enable != 0));
}
}
private boolean updateConfig(String path, String fileName, String name, int fieldType, JSONObject val) {
if (name == null) {
return false;
}
File configFile = new File(Environment.getExternalStorageDirectory(), path);
if (!configFile.exists()) {
if (val == null) {
// Should delete the config field
return true;
}
configFile.mkdirs();
}
configFile = new File(configFile, fileName);
if (!configFile.exists() && val == null) {
return true;
}
JSONObject jsonObject = JSONUtils.loadJson(configFile.getAbsolutePath());
if (jsonObject == null) {
if (val == null) {
return true;
}
jsonObject = new JSONObject();
}
if (!JSONUtils.updateJsonProperty(jsonObject, name, fieldType, val)) {
return false;
}
return JSONUtils.saveJson(configFile.getAbsolutePath(), jsonObject);
}
private String buildMntnServer(String server, int port) {
if (TextUtils.isEmpty(server) && port == 0) {
return null;
}
String url = null;
if (server.startsWith("http://") || server.startsWith("https://")) {
url = server;
} else {
if ((InetAddressUtils.isIPv4Address(server) || InetAddressUtils.isIPv6Address(server)) && port > 0) {
url = "http://" + server + ":" + Integer.toString(port) + "/";
}
}
return url;
}
private boolean updateCma(String ip, int port) {
if ((InetAddressUtils.isIPv4Address(ip) && InetAddressUtils.isIPv6Address(ip)) || port <= 0) {
return false;
}
MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(mService.getApplicationContext());
if (TextUtils.equals(ip, appConfig.server) && port == appConfig.port) {
return true;
}
appConfig.server = ip;
appConfig.port = port;
MicroPhotoContext.saveMpAppConfig(mService.getApplicationContext(), appConfig);
MicroPhotoContext.restartMpApp(mService.getApplicationContext());
return true;
}
private void upgradeApp(String url) {
FileDownloader dl = new FileDownloader();
File path = new File(MicroPhotoContext.buildAppDir(mService.getApplicationContext()), "packages");
if (!path.exists()) {
path.mkdirs();
}
File file = new File(path, "app.apk");
if (file.exists()) {
file.delete();
}
String apkPath = file.getAbsolutePath();
if (dl.download(url, apkPath)) {
Context context = mService.getApplicationContext();
SysApi.installApk(context, apkPath, context.getPackageName(), true);
}
}
private void uploadLogs(String url) {
String appDir = mService.buildAppDir();
try {
long ts = System.currentTimeMillis();//long now = android.os.SystemClock.uptimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
Date dt = new Date(ts);
final String fileName = mCmdid + "_" + format.format(dt) + ".zip";
final File file = File.createTempFile(fileName, null, new File(appDir));
if (file == null) {
return;
}
final String mpAppDir = MicroPhotoContext.buildMpAppDir(mService.getApplicationContext());
final File logDir = new File(mpAppDir + "logs" + File.separator);
if (!logDir.exists()) {
return;
}
ZipUtils.ZipFolder(logDir, file);
if (!file.exists()) {
return;
}
FileUploader fileUploader = new FileUploader(url);
fileUploader.addFilePart("file", file, fileName, "application/x-zip-compressed");
String response = fileUploader.finish();
if (response != null) {
}
} catch (Exception ex) {
}
}
private void uploadFiles(String url, List<String> paths) {
String appDir = mService.buildAppDir();
try {
long ts = System.currentTimeMillis();//long now = android.os.SystemClock.uptimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
Date dt = new Date(ts);
final String fileName = mCmdid + "_" + format.format(dt) + ".zip";
final File file = File.createTempFile(fileName, null, new File(appDir));
if (file == null) {
return;
}
// ZipUtils
// ZipUtils.ZipFiles(logDir, file);
if (!file.exists()) {
return;
}
FileUploader fileUploader = new FileUploader(url);
fileUploader.addFilePart("file", file, fileName, "application/x-zip-compressed");
String response = fileUploader.finish();
if (response != null) {
}
} catch (Exception ex) {
}
}
private void buildParams(OutputStream output) {
BufferedWriter bufferedWriter = null;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", mCmdid);
jsonObject.put("i1Version", mService.getMpAppVersion());
jsonObject.put("maintainVersion", mService.getMasterAppVersion());
bufferedWriter = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
bufferedWriter.write(jsonObject.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void postParams(OutputStream output, List<Pair<String, String>> paramsList) {
BufferedWriter bufferedWriter = null;
try {
StringBuilder stringBuilder = new StringBuilder();
for (Pair<String, String> pair : paramsList) {
if (!TextUtils.isEmpty(stringBuilder)) {
stringBuilder.append("&");
}
stringBuilder.append(URLEncoder.encode(pair.first, "UTF-8"));
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(pair.second, "UTF-8"));
bufferedWriter = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
bufferedWriter.write(stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String convertStreamToString(InputStream inputStream) {
BufferedReader bufferedReader = null;
StringBuffer stringBuffer = new StringBuffer();
String line;
try {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return stringBuffer.toString();
}
}