package com.fwupgrade.saymanss; import android.app.Service; import android.content.Intent; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; import com.fwupgrade.saymanss.deviceplug.IUsbDevicePlugDelegate; import com.fwupgrade.saymanss.deviceplug.UstorageDeviceInstance; import com.fwupgrade.saymanss.utils.AppPathInfo; import com.fwupgrade.saymanss.utils.UtilTools; import com.fwupgrade.saymanss.view.GeneralDialog; import com.jni.UStorageTestModule; import com.spca.usb.CUSBListener; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * @ProjectName: FwUpgrade * @Package: com.fwupgrade.saymanss * @ClassName: FwUpgradeService * @Description: java类作用描述 * @Author: zhanwei.li * @CreateDate: 2024/2/19 10:02 * @UpdateUser: 更新者 * @UpdateDate: 2024/2/19 10:02 * @UpdateRemark: 更新说明 * @Version: 1.0 */ public class FwUpgradeService extends Service implements IUsbDevicePlugDelegate { /** usb插入. */ private static final int USB_DEVICE_INSERT = 0; /** usb权限. */ private static final int USB_DEVICE_PERRMISSION = 1; /** usb拔出. */ private static final int USB_DEVICE_DETACHED = 2; /** usb打开. */ private static final int USB_DEVICE_OPEN = 3; /** 升级结束. */ private static final int USB_DEVICE_UPGRADE = 4; /** 显示 */ private static final int USB_DEVICE_MESSAGE = 5; private static final int UPGRADE_PRESET = 0; private static final int UPGRADE_FAIL = 3; private static final int UPGRADE_SUCCESS = 4; private CameraInfo mCamInfo = null; private static final String TAG = FwUpgradeService.class.getCanonicalName(); private IFwAidlInterface.Stub mBinder = new IFwAidlInterface.Stub() { @Override public void upgradeFw(String path, String device) throws RemoteException { Log.i(TAG,"客户端调用更新固件方法,device="+device+"_path="+path); } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); Log.i(TAG,"onCreate"); initTarget(); initData(); initDeviceSDK(); UStorageTestModule.getInstance().initUStorageDeviceModuleWithVirtualDisk(AppPathInfo.getLogPath()); } private File[] mFileList; private HashMap tty = new HashMap<>(); private final Handler mHander = new Handler(Looper.getMainLooper()) { @Override public void dispatchMessage(Message msg) { switch (msg.what) { case USB_DEVICE_INSERT: Toast.makeText(FwUpgradeService.this, "USB设备已插入", Toast.LENGTH_SHORT).show(); break; case USB_DEVICE_PERRMISSION: boolean isSuccessful = (boolean) msg.obj; if (isSuccessful) { Toast.makeText(FwUpgradeService.this, "USB设备权限申请成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(FwUpgradeService.this, "USB设备权限申请失败", Toast.LENGTH_SHORT).show(); } break; case USB_DEVICE_DETACHED: int count = (int) msg.obj; Log.i(TAG,"count="+count); if (count<2) { tty.clear(); initTarget(); int ret = UstorageDeviceInstance.getInstance().tryAgain(FwUpgradeService.this); if (ret==1){ Log.i(TAG,"发送失败结果广播给驾培"); sendToDriveTrainByBroadCast(0,1); sendToNewDriveTrainByBroadCast(0,1); } } break; case USB_DEVICE_OPEN: Log.d(TAG, "USB_DEVICE_OPEN"); CameraInfo cameraInfo = (CameraInfo) msg.obj; Toast.makeText(FwUpgradeService.this, "USB设备初始化成功,可以准备升级", Toast.LENGTH_SHORT).show(); acceptFwList(); mCamInfo = cameraInfo; executeUpgrade(mCamInfo); break; case GeneralDialog.BUTTON_CLICK_OK: break; case USB_DEVICE_UPGRADE: String devName = (String) msg.obj; int errCode = msg.arg1; int succ_num = 0, fail_num = 0; Log.d("fwup","Upgrade result:" + devName + ", errCode: " + errCode+".ttySize="+tty.size()); if (tty.containsKey(devName)) { tty.put(devName, errCode == 0? UPGRADE_SUCCESS:UPGRADE_FAIL); } for (Map.Entry entry : tty.entrySet()) { if (entry.getValue() == UPGRADE_SUCCESS) { succ_num++; } else if (entry.getValue() == UPGRADE_FAIL) { fail_num++; } } if (succ_num + fail_num == tty.size()) { Log.d(TAG, "Upgrade Finish!"); sendToNewDriveTrainByBroadCast(succ_num,tty.size()); sendToDriveTrainByBroadCast(succ_num,tty.size()); // System.exit(0); } break; case USB_DEVICE_MESSAGE: String text = (String) msg.obj; Toast.makeText(FwUpgradeService.this, text, Toast.LENGTH_SHORT).show(); break; } } }; private void sendToNewDriveTrainByBroadCast(int succ_num,int ttySize) { Intent intent = new Intent(); intent.putExtra("result", succ_num == ttySize? 0 : 1); //0-成功 intent.setAction("com.fwupgrade.saymanss.UPGRADE_COMPLETE"); intent.setPackage("safeluck.drive.training"); sendBroadcast(intent); } private void sendToDriveTrainByBroadCast(int succ_num,int ttySize) { Intent intent = new Intent(); intent.putExtra("result", succ_num == ttySize? 0 : 1); intent.setAction("com.fwupgrade.saymanss.UPGRADE_COMPLETE"); intent.setPackage("demo1.tech.anyun.com.myapplication"); sendBroadcast(intent); } // 每次升级路径值最小的 private void initTarget() { ArrayList targets = UstorageDeviceInstance.getInstance().acceptOTGDeviceInfo((UsbManager) getSystemService(USB_SERVICE)); String min = "Z"; for (UsbDevice usbDevice: targets) { if (usbDevice.getDeviceName().compareTo(min) < 0) { min = usbDevice.getDeviceName(); } } Log.i(TAG,"min="+min); tty.put(min, UPGRADE_PRESET); } /** * 获取fw列表 */ private void acceptFwList() { Log.d(TAG,"acceptFwList: "); File file = new File(AppPathInfo.getFwSavePath()); File[] files = file.listFiles(); if (files != null && files.length > 0) { mFileList = files; } else { } } private void executeUpgrade(CameraInfo cameraInfo) { if (mFileList != null && mFileList.length > 0) { Log.i(TAG,"executeUpgrade"); new Thread(new Update(cameraInfo, mFileList[0])).start(); } } /** * 初始化数据 */ private void initData() { UtilTools.createFolderInSdcard(AppPathInfo.getFwSavePath()); } /** * UstorageDeviceSDK初始化. */ private void initDeviceSDK() { int count = 0 ; int ret = UstorageDeviceInstance.getInstance().tryAttcheDeviceHandle(FwUpgradeService.this, FwUpgradeService.this); Log.i(TAG,"initDeviceSDk,ret="+ret); if (ret==1){ ++count; Log.i(TAG,"再次的初始化"); Message message = Message.obtain(); message.obj = count; message.what = USB_DEVICE_DETACHED; mHander.sendMessageDelayed(message,1000); } } @Override public void usbDeviceInsert() { Log.d(TAG,"usbDeviceInsert"); } @Override public void permissionFinish(boolean isSuccessful, CUSBListener.UsbControlBlock ctrlBlock) { synchronized (this) { Message msg = Message.obtain(); msg.obj = isSuccessful; msg.what = USB_DEVICE_PERRMISSION; mHander.sendMessage(msg); Log.d(TAG,"permissionFinish:" + isSuccessful); if (isSuccessful && ctrlBlock != null) { initFwUpgrade(ctrlBlock); }else{ sendToDriveTrainByBroadCast(0,1); sendToNewDriveTrainByBroadCast(0,1); } } } @Override public void usbDeviceDetached() { Log.d(TAG,"usbDeviceDetached"); } /** * 初始化升级环境 */ private void initFwUpgrade(CUSBListener.UsbControlBlock ctrlBlock) { final int vendorId = ctrlBlock.getVenderId(); final int productId = ctrlBlock.getProductId(); int fileDescriptor = ctrlBlock.getFileDescriptor(); int busNum = ctrlBlock.getBusNum(); int devNum = ctrlBlock.getDevNum(); boolean isTarget = false; String usbfsName = getUSBFSName(ctrlBlock); String devName = ctrlBlock.getDeviceName(); String serial = ctrlBlock.getSerial(); Log.d(TAG,"sonixCamInit " + String.format("vendorId:%d productId:%d fileDescriptor:%d busNum:%d devNum:%d usbfsName:%s devName:%s serial:%s,tty.size=%d", vendorId, productId, fileDescriptor, busNum, devNum, usbfsName, devName, serial,tty.size())); if (tty.containsKey(devName) && tty.get(devName) == 0) { isTarget = true; tty.put(devName, 1); } if (!isTarget) { Log.d(TAG,"Not sonixCam, close"); ctrlBlock.close(); return; } Log.d(TAG,"Is sonixCam, upgrade!"); Message msg = Message.obtain(); //msg.obj = errCode == 0; msg.obj = new CameraInfo(vendorId, productId, fileDescriptor, busNum, devNum, usbfsName, devName); msg.what = USB_DEVICE_OPEN; mHander.sendMessage(msg); } private final String getUSBFSName(final CUSBListener.UsbControlBlock ctrlBlock) { String result = null; final String name = ctrlBlock.getDeviceName(); final String[] v = !TextUtils.isEmpty(name) ? name.split("/") : null; if ((v != null) && (v.length > 2)) { final StringBuilder sb = new StringBuilder(v[0]); for (int i = 1; i < v.length - 2; i++) sb.append("/").append(v[i]); result = sb.toString(); } if (TextUtils.isEmpty(result)) { // Log.w(TAG, "failed to get USBFS path, try to use default path:" + name); result = "/dev/bus/usb"; } return result; } class Update implements Runnable { CameraInfo cam; File file; public Update(CameraInfo cam, File file) { this.cam = cam; this.file = file; } @Override public void run() { int errCode = fwUpdate(cam, file); Message msg = Message.obtain(); msg.obj = cam.devName; msg.arg1 = errCode; msg.what = USB_DEVICE_UPGRADE; mHander.sendMessage(msg); } } int fwUpdate(final CameraInfo cam, final File file) { int errCode = -1; int retry = 0; synchronized (this) { Log.d(TAG, String.format("Upgrade %s...", cam.devName)); Message msg = Message.obtain(); msg.obj = String.format("Upgrade %s...", cam.devName); msg.what = USB_DEVICE_MESSAGE; mHander.sendMessage(msg); while (retry++ <= 3) { errCode = UStorageTestModule.getInstance().sonixCamInit(cam.vendorId, cam.productId, cam.fileDescriptor, cam.busNum, cam.devNum, cam.usbfsName); Log.d(TAG, "Initialize result:" + errCode); if (errCode != 0) { return errCode; } errCode = UStorageTestModule.getInstance().updateFW(file.getPath()); Log.d(TAG, "Upgrade result:" + errCode); UStorageTestModule.getInstance().sonixCamUnInit(); if (errCode == 0) { return 0; } SystemClock.sleep(1000); } } return errCode; } static class CameraInfo { int vendorId; int productId; int fileDescriptor; int busNum; int devNum; String usbfsName; String devName; public CameraInfo(int vendorId, int productId, int fileDescriptor, int busNum, int devNum, String usbfsName, String devName) { this.vendorId = vendorId; this.productId = productId; this.fileDescriptor = fileDescriptor; this.busNum = busNum; this.devNum = devNum; this.usbfsName = usbfsName; this.devName = devName; } } }