package com.fwupgrade.saymanss; import android.Manifest; import android.annotation.TargetApi; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.icu.text.MessagePattern; import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; import com.fwupgrade.saymanss.adapter.FwFileListAdapter; import com.fwupgrade.saymanss.deviceplug.IUsbDevicePlugDelegate; import com.fwupgrade.saymanss.deviceplug.UstorageDeviceInstance; import com.fwupgrade.saymanss.utils.AppPathInfo; import com.fwupgrade.saymanss.utils.SystemUtil; import com.fwupgrade.saymanss.utils.UtilTools; import com.fwupgrade.saymanss.view.GeneralDialog; import com.jni.UStorageTestModule; import com.spca.usb.CUSBListener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import app.dinus.com.loadingdrawable.LoadingView; public class HomePageActivity extends AppCompatActivity implements IUsbDevicePlugDelegate, AdapterView.OnItemClickListener { static final String TAG = "fwup"; /** 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_PREPARE = 1; private static final int UPGRADE_START = 2; private static final int UPGRADE_FAIL = 3; private static final int UPGRADE_SUCCESS = 4; /** 需要请求授权的权限. */ private ArrayList needRPDatas; /** 应用所需要请求的所有权限. */ private String[] needRequestPermissions = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; /** 动态权限请求码. */ final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; protected TextView mTitle; /** 返回 */ protected TextView mAppVersion; /** LoadingView */ private LoadingView loadingView; /** 升级 */ private TextView mFwUpDataBtn; /** 提示 */ private TextView mFwUpNo; /** fw list */ protected ListView mListView; private File[] mFileList; private HashMap tty = new HashMap<>(); private Handler mHander = new Handler() { @Override public void dispatchMessage(Message msg) { switch (msg.what) { case USB_DEVICE_INSERT: mFwUpDataBtn.setText("USB设备已插入"); break; case USB_DEVICE_PERRMISSION: boolean isSuccessful = (boolean) msg.obj; if (isSuccessful) { mFwUpDataBtn.setText("USB设备权限申请成功"); } else { mFwUpDataBtn.setText("USB设备权限申请失败"); } break; case USB_DEVICE_DETACHED: mFwUpDataBtn.setEnabled(false); mFwUpDataBtn.setText("USB设备已拔出,等待设备插入"); break; case USB_DEVICE_OPEN: Log.d(TAG, "USB_DEVICE_OPEN"); CameraInfo cameraInfo = (CameraInfo)msg.obj; mFwUpDataBtn.setText("USB设备初始化成功,可以准备升级"); mFwUpDataBtn.setEnabled(true); acceptFwList(); if (mFileList != null && mFileList.length > 0) { new Thread(new Update(cameraInfo, mFileList[0])).start(); } /*boolean initSuccessful = (boolean) msg.obj; if (initSuccessful) { mFwUpDataBtn.setText("USB设备初始化成功,可以准备升级"); mFwUpDataBtn.setEnabled(true); acceptFwList(); } else { mFwUpDataBtn.setText("USB设备初始化失败"); mFwUpDataBtn.setEnabled(false); }*/ break; case GeneralDialog.BUTTON_CLICK_OK: /*File file = (File) msg.obj; startFwUpdata(file);*/ break; case USB_DEVICE_UPGRADE: /*loadingView.setVisibility(View.GONE); boolean upgradeSuccessful = (boolean) msg.obj; int errCode = msg.arg1; if (upgradeSuccessful) { mFwUpDataBtn.setText("升级成功"); } else { if (errCode == -1100) { mFwUpDataBtn.setText("非法固件"); } else { mFwUpDataBtn.setText("升级失败"); } }*/ String devName = (String) msg.obj; int errCode = msg.arg1; int succ_num = 0, fail_num = 0; Log.d("fwup","Upgrade result:" + devName + ", errCode: " + errCode); 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!"); Intent intent = new Intent(); intent.putExtra("result", succ_num == tty.size()? 0 : 1); intent.setAction("com.fwupgrade.saymanss.UPGRADE_COMPLETE"); intent.setPackage("safeluck.drive.training"); sendBroadcast(intent); intent = new Intent(); intent.putExtra("result", succ_num == tty.size()? 0 : 1); intent.setAction("com.fwupgrade.saymanss.UPGRADE_COMPLETE"); intent.setPackage("demo1.tech.anyun.com.myapplication"); sendBroadcast(intent); finish(); System.exit(0); } break; case USB_DEVICE_MESSAGE: String text = (String) msg.obj; mFwUpDataBtn.setText(text); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_homepage); SystemUtil.setStatusBarColor(this); initView(); checkPermission(); initTarget(); initData(); initListener(); initDeviceSDK(); UStorageTestModule.getInstance().initUStorageDeviceModuleWithVirtualDisk(AppPathInfo.getLogPath()); } @Override protected void onNewIntent(Intent intent) { Log.d(TAG, "onNewIntent"); super.onNewIntent(intent); initDeviceSDK(); } @Override protected void onDestroy() { super.onDestroy(); } /** * 初始化view */ private void initView() { //顶部条 mTitle = (TextView) findViewById(R.id.app_topbar_center_text); mAppVersion = (TextView) findViewById(R.id.app_topbar_left_text); loadingView = (LoadingView) findViewById(R.id.progress_loading); loadingView.setColorFilter(getResources().getColor(R.color.apptakeaction)); mFwUpDataBtn = (TextView) findViewById(R.id.app_fwupdata_btn); mFwUpNo = (TextView) findViewById(R.id.app_topbar_no); mListView = (ListView) findViewById(R.id.app_fw_list); } // 每次升级路径值最小的 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(); } } tty.put(min, UPGRADE_PRESET); } /** * 初始化数据 */ private void initData() { UtilTools.createFolderInSdcard(AppPathInfo.getFwSavePath()); mTitle.setText("FwUpgradeDemo"); mFwUpDataBtn.setEnabled(false); mAppVersion.setVisibility(View.VISIBLE); setAppVersionInfo(); } /** * 设置app版本 */ private void setAppVersionInfo() { PackageManager manager = getPackageManager(); String version = ""; try { PackageInfo info = manager.getPackageInfo(getPackageName(), 0); version = info.versionName; } catch (PackageManager.NameNotFoundException e) { version = ""; } mAppVersion.setText("App版本:" + version); } /** * UstorageDeviceSDK初始化. */ private void initDeviceSDK() { UstorageDeviceInstance.getInstance().tryAttcheDeviceHandle(HomePageActivity.this, HomePageActivity.this); // Thread thread = new Thread() { // @Override // public void run() { // UstorageDeviceInstance.getInstance().tryAttcheDeviceHandle(HomePageActivity.this, HomePageActivity.this); // } // }; // thread.start(); } /** * 初始化 监听 */ private void initListener() { mListView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView adapterView, View view, int position, long l) { int visibility = loadingView.getVisibility(); if (mFileList != null && visibility != View.VISIBLE) { File file = mFileList[position]; String point = "确定升级此固件吗?"; GeneralDialog generalDialog = new GeneralDialog(this, R.style.wdDialog, mHander, point, file); generalDialog.setCanceledOnTouchOutside(false); generalDialog.show(); } } /** * 获取fw列表 */ private void acceptFwList() { Log.d("fwup","acceptFwList: "); loadingView.setVisibility(View.GONE); File file = new File(AppPathInfo.getFwSavePath()); File[] files = file.listFiles(); if (files != null && files.length > 0) { mFwUpNo.setVisibility(View.GONE); mListView.setVisibility(View.VISIBLE); mFileList = files; FwFileListAdapter apListAdapter = new FwFileListAdapter(this, files); mListView.setAdapter(apListAdapter); } else { mFwUpNo.setVisibility(View.VISIBLE); mListView.setVisibility(View.GONE); } } @Override public void usbDeviceInsert() { Log.d("fwup","usbDeviceInsert"); // mHander.sendEmptyMessage(USB_DEVICE_INSERT); } @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("fwup","permissionFinish:" + isSuccessful); if (isSuccessful && ctrlBlock != null) { initFwUpgrade(ctrlBlock); } } } @Override public void usbDeviceDetached() { Log.d("fwup","usbDeviceDetached"); // mHander.sendEmptyMessage(USB_DEVICE_DETACHED); // unInitFwUpgrade(); } /** * 初始化升级环境 */ private void unInitFwUpgrade() { int errCode = UStorageTestModule.getInstance().sonixCamUnInit(); } static class UpdateTarget { String devName; int status; public UpdateTarget(String devName, int status) { this.devName = devName; this.status = status; } } 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; } } /** * 初始化升级环境 */ 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("fwup","sonixCamInit " + String.format("vendorId:%d productId:%d fileDescriptor:%d busNum:%d devNum:%d usbfsName:%s devName:%s serial:%s", vendorId, productId, fileDescriptor, busNum, devNum, usbfsName, devName, serial)); //final int errCode = UStorageTestModule.getInstance().sonixCamInit(vendorId, productId, fileDescriptor, busNum, devNum, usbfsName); //Log.d("fwup","sonixCamInit errCode:" + errCode); /*runOnUiThread(new Runnable() { @Override public void run() { UtilTools.showToast(HomePageActivity.this, "vid: " + vendorId + " pid: " + productId + " err: " + errCode); } });*/ if (tty.containsKey(devName) && tty.get(devName) == 0) { isTarget = true; tty.put(devName, 1); } if (!isTarget) { Log.d("fwup","Not sonixCam, close"); ctrlBlock.close(); return; } Log.d("fwup","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; } /** * 升级 * @param file */ private void startFwUpdata(final File file) { loadingView.setVisibility(View.VISIBLE); mFwUpDataBtn.setText("正在升级,请勿断开连接"); Thread thread = new Thread() { @Override public void run() { int errCode = UStorageTestModule.getInstance().updateFW(file.getPath()); Log.d("fwup","errCode: " + errCode); Message msg = Message.obtain(); msg.obj = errCode == 0; msg.arg1 = errCode; msg.what = USB_DEVICE_UPGRADE; mHander.sendMessage(msg); } }; thread.start(); } 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; } // -----------------------------------------------权限申请 相关------------------------------------------ /** * 检查权限 */ private void checkPermission() { if (Build.VERSION.SDK_INT >= 23) { needRPDatas = checkAllPermissions(); if (needRPDatas.size() == 0) { initData(); } else { requestPermissions(needRPDatas.toArray(new String[needRPDatas.size()]), REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); } } else { initData(); } } /** * 判断所有需要的权限是否已经授权. * @return 所有授权: true; 有任何一个没授权: false; */ public ArrayList checkAllPermissions() { ArrayList needRequestDatas = new ArrayList<>(); for (String permission : needRequestPermissions) { if (checkPermission(permission)) { needRequestDatas.add(permission); } } return needRequestDatas; } /** * 判断权限是否没有授权.. * @param permission 权限名称. * @return 没授权: true; 授权:false */ @TargetApi(Build.VERSION_CODES.M) private boolean checkPermission(String permission) { return checkSelfPermission(permission) == PackageManager.PERMISSION_DENIED; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: { boolean isAllPass = true; for (int i = 0; i < permissions.length; i++) { final String permissionResoult = permissions[i]; if (isAllPass) { for (String permission : needRPDatas) { if (permissionResoult.equals(permission) && grantResults[i] == PackageManager.PERMISSION_DENIED) { isAllPass = false; break; } } } else { break; } } if(isAllPass) { //初始化 } else { UtilTools.showToast(this, "请前往设置检查存储权限并打开"); } } break; default: break; } } /** * 这里用来实现,再点一次返回键退出应用 * @param keyCode * @param event * @return */ private long exitTime = 0; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if (System.currentTimeMillis() - exitTime > 2000) { UtilTools.showToast(this, "再按一次退出"); exitTime = System.currentTimeMillis(); } else { finish(); System.exit(0); } return true; } return super.onKeyDown(keyCode, event); } }