lzw
2024-02-19 a9ac419b3564590e5fccba048988e287490bc79c
1.修改成无界面的apk
2.修改成服务
5个文件已修改
2个文件已添加
423 ■■■■■ 已修改文件
UStorageTest/build.gradle 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/aidl/com/fwupgrade/saymanss/IFwAidlInterface.aidl 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/fwupgrade/saymanss/FwUpgradeService.java 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
gradle.properties 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UStorageTest/build.gradle
@@ -2,7 +2,6 @@
android {
    compileSdkVersion 27
    buildToolsVersion "27.0.3"
    defaultConfig {
        minSdkVersion 15
app/build.gradle
@@ -2,16 +2,17 @@
android {
    compileSdkVersion 27
//    buildToolsVersion "27.0.3"
    defaultConfig {
        applicationId "com.fwupgrade.saymanss"
        minSdkVersion 15
        minSdkVersion 21
        targetSdkVersion 27
        versionCode 6
        versionName "1.6"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildFeatures{
        aidl true
    }
    signingConfigs {
        release {
            storeFile file("../key/key.jks")
app/src/main/AndroidManifest.xml
@@ -14,28 +14,8 @@
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".HomePageActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar"
            android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateAlwaysHidden|adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
<!--            <intent-filter>-->
<!--                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>-->
<!--                <action android:name="android.hardware.usb.action.ACTION_USB_DEVICE_DETACHED"/>-->
<!--                <action android:name="android.hardware.usb.action.USB_STATE"/>-->
<!--            </intent-filter>-->
<!--            <meta-data-->
<!--                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"-->
<!--                android:resource="@xml/device_filter"/>-->
        </activity>
        <service android:name=".FwUpgradeService" android:exported="true"/>
    </application>
</manifest>
app/src/main/aidl/com/fwupgrade/saymanss/IFwAidlInterface.aidl
New file
@@ -0,0 +1,9 @@
// IFwAidlInterface.aidl
package com.fwupgrade.saymanss;
// Declare any non-default types here with import statements
interface IFwAidlInterface {
    void upgradeFw(String path,String device);
}
app/src/main/java/com/fwupgrade/saymanss/FwUpgradeService.java
New file
@@ -0,0 +1,377 @@
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.Build;
import android.os.Handler;
import android.os.IBinder;
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.view.View;
import android.widget.Toast;
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.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();
    }
    private File[] mFileList;
    private HashMap<String, Integer> tty = new HashMap<>();
    private final Handler mHander = new Handler() {
        @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:
                    Toast.makeText(FwUpgradeService.this, "USB设备已拔出,等待设备插入", Toast.LENGTH_SHORT).show();
                    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);
                    if (tty.containsKey(devName)) {
                        tty.put(devName, errCode == 0? UPGRADE_SUCCESS:UPGRADE_FAIL);
                    }
                    for (Map.Entry<String, Integer> 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);
//                        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 initTarget() {
        ArrayList<UsbDevice> 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);
    }
    /**
     * 获取fw列表
     */
    private void acceptFwList() {
        Log.d("fwup","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() {
        UstorageDeviceInstance.getInstance().tryAttcheDeviceHandle(FwUpgradeService.this, FwUpgradeService.this);
    }
    @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);
            }
        }
    }
    @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", vendorId, productId, fileDescriptor, busNum, devNum, usbfsName, devName, serial));
        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;
        }
    }
}
build.gradle
@@ -7,7 +7,7 @@
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.0'
        classpath 'com.android.tools.build:gradle:4.2.2'
        
        // NOTE: Do not place your application dependencies here; they belong
gradle.properties
@@ -9,10 +9,11 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
org.gradle.jvmargs=-Xmx1536m --add-opens java.base/java.io=ALL-UNNAMED
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.enableAapt2=false