has been a while since I've touched Android!
This commit is contained in:
parent
829de00a21
commit
7f0babed06
|
@ -29,12 +29,12 @@ public class DfuUpload {
|
|||
localDfuImageFileName = localFolder + File.separator + DFU_FILE_NAME;
|
||||
}
|
||||
|
||||
void fileOperation(final TextView mResultView) {
|
||||
void downloadFileIfNotPresent(final TextView mResultView) {
|
||||
if (new File(this.localFullFile).exists()) {
|
||||
mResultView.append(this.BUNDLE_FILE + " found!\n");
|
||||
mResultView.append(BUNDLE_FILE + " found!\n");
|
||||
uncompressFile(this.localFullFile, this.localFolder, this.localDfuImageFileName, mResultView);
|
||||
} else {
|
||||
mResultView.append(this.BUNDLE_FILE + " not found!\n");
|
||||
mResultView.append(BUNDLE_FILE + " not found!\n");
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
|
@ -43,30 +43,15 @@ public class DfuUpload {
|
|||
ConnectionAndMeta c = new ConnectionAndMeta(BUNDLE_FILE).invoke(ConnectionAndMeta.BASE_URL_LATEST);
|
||||
ConnectionAndMeta.downloadFile(localFullFile, c, new ConnectionAndMeta.DownloadProgressListener() {
|
||||
@Override
|
||||
public void onPercentage(final int currentProgress) {
|
||||
mResultView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mResultView.append("Downloading " + currentProgress + "\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
mResultView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mResultView.append("Downloaded! " + "\n");
|
||||
public void onPercentage(final int currentPercentage) {
|
||||
mResultView.post(() -> mResultView.append("Downloaded " + currentPercentage + "%\n"));
|
||||
}
|
||||
});
|
||||
mResultView.post(() -> mResultView.append("Downloaded! " + "\n"));
|
||||
uncompressFile(localFullFile, localFolder, localDfuImageFileName, mResultView);
|
||||
|
||||
} catch (IOException | KeyManagementException | NoSuchAlgorithmException e) {
|
||||
mResultView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mResultView.append("Error downloading " + e + "\n");
|
||||
}
|
||||
});
|
||||
mResultView.post(() -> mResultView.append("Error downloading " + e + "\n"));
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package com.rusefi.app;
|
||||
|
||||
public enum PermissionGrantedAction {
|
||||
DFU,
|
||||
DASHBOARD,
|
||||
}
|
|
@ -60,6 +60,7 @@ import com.rusefi.proxy.NetworkConnector;
|
|||
import com.rusefi.proxy.NetworkConnectorContext;
|
||||
import com.rusefi.ui.StatusConsumer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
public class rusEFI extends Activity {
|
||||
|
@ -71,20 +72,20 @@ public class rusEFI extends Activity {
|
|||
//
|
||||
// protected static final int DFU_DETACH_TIMEOUT = 1000;
|
||||
|
||||
private static final String VERSION = "rusEFI app v0.0000008\n";
|
||||
private static final String VERSION = "rusEFI app v0.20220524\n";
|
||||
|
||||
/* UI elements */
|
||||
private TextView mStatusView;
|
||||
private TextView mResultView;
|
||||
private TextView mResultView; // global dump of all messages
|
||||
private TextView broadcastStatus;
|
||||
private EditText authToken;
|
||||
private EditText authTokenUI;
|
||||
private TextView authStatusMessage;
|
||||
private TextView authStatusClickableUrl;
|
||||
|
||||
private UsbManager usbManager;
|
||||
private DfuUpload dfuUpload;
|
||||
private SoundBroadcast soundBroadcast = new SoundBroadcast();
|
||||
|
||||
private PermissionGrantedAction onPermissionGrantedAction;
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
|
@ -102,6 +103,7 @@ public class rusEFI extends Activity {
|
|||
findViewById(R.id.buttonDfu).setVisibility(View.GONE);
|
||||
|
||||
broadcastStatus = findViewById(R.id.broadcastStatus);
|
||||
broadcastStatus.setVisibility(View.GONE);
|
||||
|
||||
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||
|
||||
|
@ -110,8 +112,8 @@ public class rusEFI extends Activity {
|
|||
|
||||
mStatusView = findViewById(R.id.text_status);
|
||||
mResultView = findViewById(R.id.text_result);
|
||||
authToken = findViewById(R.id.authToken);
|
||||
authToken.addTextChangedListener(new TextWatcher() {
|
||||
authTokenUI = findViewById(R.id.authToken);
|
||||
authTokenUI.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||
|
||||
|
@ -123,7 +125,7 @@ public class rusEFI extends Activity {
|
|||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
String text = authToken.getText().toString();
|
||||
String text = authTokenUI.getText().toString();
|
||||
if (AuthTokenUtil.isToken(text)) {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(rusEFI.this);
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
@ -143,13 +145,14 @@ public class rusEFI extends Activity {
|
|||
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
|
||||
registerReceiver(mUsbReceiver, filter);
|
||||
|
||||
mResultView.append(VERSION);
|
||||
visibleLogAppend(VERSION);
|
||||
|
||||
dfuUpload = new DfuUpload(this);
|
||||
|
||||
dfuUpload.fileOperation(mResultView);
|
||||
String authToken = getAuthToken();
|
||||
this.authToken.setText(authToken);
|
||||
//dfuUpload.downloadFileIfNotPresent(mResultView);
|
||||
|
||||
String authToken = readPersistedAuthToken();
|
||||
authTokenUI.setText(authToken);
|
||||
int visibility = AuthTokenUtil.isToken(authToken) ? View.GONE : View.VISIBLE;
|
||||
authStatusMessage.setVisibility(visibility);
|
||||
authStatusClickableUrl.setVisibility(visibility);
|
||||
|
@ -159,7 +162,7 @@ public class rusEFI extends Activity {
|
|||
// SoundBroadcast.checkOrRequestPermission(this);
|
||||
}
|
||||
|
||||
private String getAuthToken() {
|
||||
private String readPersistedAuthToken() {
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(rusEFI.this);
|
||||
return preferences.getString(AuthTokenUtil.AUTH_TOKEN, "");
|
||||
}
|
||||
|
@ -185,8 +188,13 @@ public class rusEFI extends Activity {
|
|||
if (ACTION_USB_PERMISSION.equals(action)) {
|
||||
synchronized (this) {
|
||||
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
|
||||
UsbDevice dfuDevice = DfuDeviceLocator.findDevice(usbManager);
|
||||
doDfuUpdate(dfuDevice, rusEFI.this.mResultView);
|
||||
if (onPermissionGrantedAction == PermissionGrantedAction.DFU) {
|
||||
|
||||
UsbDevice dfuDevice = DfuDeviceLocator.findDevice(usbManager);
|
||||
doDfuUpdate(dfuDevice);
|
||||
} else if (onPermissionGrantedAction == PermissionGrantedAction.DASHBOARD) {
|
||||
connectDashboard();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,45 +203,49 @@ public class rusEFI extends Activity {
|
|||
|
||||
private void switchOrProgramDfu() {
|
||||
UsbDevice dfuDevice = DfuDeviceLocator.findDevice(usbManager);
|
||||
|
||||
if (dfuDevice != null) {
|
||||
dfuUpdate(dfuDevice);
|
||||
} else {
|
||||
mResultView.append("No DFU device\n");
|
||||
if (dfuDevice == null) {
|
||||
visibleLogAppend("No DFU device\n");
|
||||
switchToDfu();
|
||||
// once device is in DFU mode we expect what exactly to happen?
|
||||
} else if (!usbManager.hasPermission(dfuDevice)) {
|
||||
requestUsbPermission(dfuDevice, PermissionGrantedAction.DFU);
|
||||
} else {
|
||||
doDfuUpdate(dfuDevice);
|
||||
}
|
||||
}
|
||||
|
||||
public void visibleLogAppend(String s) {
|
||||
CharSequence current = mResultView.getText();
|
||||
mResultView.setText(s + "\n" + current);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void switchToDfu() {
|
||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(mStatusView, mResultView, usbManager);
|
||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(this, mStatusView, usbManager);
|
||||
if (serial == null) {
|
||||
// error already reported to mStatusView
|
||||
return;
|
||||
}
|
||||
|
||||
mResultView.append("Switching to DFU\n");
|
||||
visibleLogAppend("Switching to DFU\n");
|
||||
DfuHelper.sendDfuRebootCommand(serial, StatusConsumer.VOID);
|
||||
}
|
||||
|
||||
private void dfuUpdate(UsbDevice dfuDevice) {
|
||||
if (usbManager.hasPermission(dfuDevice)) {
|
||||
doDfuUpdate(dfuDevice, mResultView);
|
||||
} else {
|
||||
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
|
||||
usbManager.requestPermission(dfuDevice, mPermissionIntent);
|
||||
}
|
||||
public void requestUsbPermission(UsbDevice usbDevice, PermissionGrantedAction action) {
|
||||
// why do we not have similar 'request serial USB permission'?
|
||||
onPermissionGrantedAction = action;
|
||||
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
|
||||
usbManager.requestPermission(usbDevice, mPermissionIntent);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void doDfuUpdate(UsbDevice dfuDevice, TextView mResultView) {
|
||||
private void doDfuUpdate(UsbDevice dfuDevice) {
|
||||
mStatusView.setText("rusEFI: DFU detected");
|
||||
DfuDeviceLocator.Result dfu = new DfuDeviceLocator().openDfu(usbManager, dfuDevice);
|
||||
|
||||
DfuImage dfuImage = new DfuImage();
|
||||
dfuImage.read(dfuUpload.localDfuImageFileName);
|
||||
mResultView.append("Image size " + dfuImage.getImageSize() + "\n");
|
||||
visibleLogAppend("Image size " + dfuImage.getImageSize() + "\n");
|
||||
|
||||
DfuConnection connection = new AndroidDfuConnection(dfu.getConnection(), dfu.getInterfaceIndex(), dfu.getTransferSize(), dfu.getFlashRange());
|
||||
|
||||
|
@ -244,12 +256,16 @@ public class rusEFI extends Activity {
|
|||
|
||||
DfuLogic.uploadImage(logger, connection, dfuImage, dfu.getFlashRange());
|
||||
} catch (IllegalStateException e) {
|
||||
this.mResultView.append("Error " + e + "\n");
|
||||
visibleLogAppend("Error " + e + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void onConnectButton(View view) {
|
||||
connectDashboard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user touches the button
|
||||
* Called when the user touches a button
|
||||
*/
|
||||
public void sendMessage(View view) {
|
||||
if (view.getId() == R.id.buttonDfu) {
|
||||
|
@ -259,7 +275,7 @@ public class rusEFI extends Activity {
|
|||
} else if (view.getId() == R.id.buttonBroadcast) {
|
||||
startService(new Intent(this, SerialService.class));
|
||||
|
||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(mStatusView, mResultView, usbManager);
|
||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(this, mStatusView, usbManager);
|
||||
if (serial == null) {
|
||||
// error already reported to mStatusView
|
||||
Snackbar mySnackbar = Snackbar.make(view, "No ECU detected", BaseTransientBottomBar.LENGTH_LONG);
|
||||
|
@ -276,48 +292,65 @@ public class rusEFI extends Activity {
|
|||
}));
|
||||
linkManager.getConnector().connectAndReadConfiguration(new BinaryProtocol.Arguments(true),
|
||||
new ConnectionStateListener() {
|
||||
@Override
|
||||
public void onConnectionEstablished() {
|
||||
mResultView.post(() -> mResultView.append(new Date() + " On connection established\n"));
|
||||
@Override
|
||||
public void onConnectionEstablished() {
|
||||
mResultView.post(() -> visibleLogAppend(new Date() + " On connection established\n"));
|
||||
|
||||
NetworkConnectorContext context = new NetworkConnectorContext();
|
||||
NetworkConnector.ActivityListener oncePerSecondStatistics = new NetworkConnector.ActivityListener() {
|
||||
long previousTime;
|
||||
NetworkConnectorContext context = new NetworkConnectorContext();
|
||||
NetworkConnector.ActivityListener oncePerSecondStatistics = new NetworkConnector.ActivityListener() {
|
||||
long previousTime;
|
||||
|
||||
@Override
|
||||
public void onActivity(IoStream targetEcuSocket) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (now - previousTime < Timeouts.SECOND) {
|
||||
// only update status once per second
|
||||
return;
|
||||
}
|
||||
previousTime = now;
|
||||
broadcastStatus.post(() -> broadcastStatus.setText(targetEcuSocket.getBytesIn() + "/" + targetEcuSocket.getBytesOut()));
|
||||
}
|
||||
};
|
||||
NetworkConnector.NetworkConnectorResult result = new NetworkConnector().start(NetworkConnector.Implementation.Android,
|
||||
readPersistedAuthToken(), context, new NetworkConnector.ReconnectListener() {
|
||||
@Override
|
||||
public void onReconnect() {
|
||||
}
|
||||
}, linkManager, oncePerSecondStatistics);
|
||||
|
||||
mResultView.post(() -> visibleLogAppend(new Date() + " Broadcast: " + result + "\n"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivity(IoStream targetEcuSocket) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (now - previousTime < Timeouts.SECOND) {
|
||||
return;
|
||||
}
|
||||
previousTime = now;
|
||||
broadcastStatus.post(() -> broadcastStatus.setText(targetEcuSocket.getBytesIn() + "/" + targetEcuSocket.getBytesOut()));
|
||||
public void onConnectionFailed() {
|
||||
mResultView.post(() -> visibleLogAppend("Connection failed\n"));
|
||||
}
|
||||
};
|
||||
NetworkConnector.NetworkConnectorResult result = new NetworkConnector().start(NetworkConnector.Implementation.Android,
|
||||
getAuthToken(), context, new NetworkConnector.ReconnectListener() {
|
||||
@Override
|
||||
public void onReconnect() {
|
||||
}
|
||||
}, linkManager, oncePerSecondStatistics);
|
||||
});
|
||||
|
||||
mResultView.post(() -> mResultView.append(new Date() + " Broadcast: " + result + "\n"));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed() {
|
||||
mResultView.post(() -> mResultView.append("Connection failed\n"));
|
||||
}
|
||||
});
|
||||
|
||||
Snackbar mySnackbar = Snackbar.make(view, "Broadcasting with " + getAuthToken(), BaseTransientBottomBar.LENGTH_LONG);
|
||||
Snackbar mySnackbar = Snackbar.make(view, "Broadcasting with " + readPersistedAuthToken(), BaseTransientBottomBar.LENGTH_LONG);
|
||||
mySnackbar.show();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void connectDashboard() {
|
||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(this, mStatusView, usbManager);
|
||||
if (serial == null) {
|
||||
// error already reported to mStatusView
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String signature = BinaryProtocol.getSignature(serial);
|
||||
visibleLogAppend("Connected to " + signature);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.rusefi.app.serial;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.widget.TextView;
|
||||
|
@ -11,6 +12,8 @@ import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
|||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
||||
import com.opensr5.io.DataListener;
|
||||
import com.rusefi.app.PermissionGrantedAction;
|
||||
import com.rusefi.app.rusEFI;
|
||||
import com.rusefi.binaryprotocol.IncomingDataBuffer;
|
||||
import com.rusefi.dfu.DfuLogic;
|
||||
import com.rusefi.io.ByteReader;
|
||||
|
@ -41,18 +44,35 @@ public class AndroidSerial extends AbstractIoStream {
|
|||
dataBuffer = createDataBuffer("");
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Nullable
|
||||
public static AndroidSerial getAndroidSerial(TextView mStatusView, TextView mResultView, UsbManager usbManager) {
|
||||
private static UsbSerialDriver getSerialDriver(rusEFI rusEFI, TextView mStatusView, UsbManager usbManager, PermissionGrantedAction action) {
|
||||
List<UsbSerialDriver> availableDrivers = findUsbSerial(usbManager);
|
||||
if (availableDrivers.isEmpty()) {
|
||||
mStatusView.setText("Serial not found");
|
||||
mResultView.append("No serial devices " + new Date() + "\n");
|
||||
rusEFI.visibleLogAppend("No serial devices " + new Date() + "\n");
|
||||
return null;
|
||||
}
|
||||
mStatusView.setText("rusEFI: " + availableDrivers.size() + " device(s)");
|
||||
|
||||
UsbSerialDriver driver = availableDrivers.get(0);
|
||||
|
||||
UsbDevice usbDevice = driver.getDevice();
|
||||
if (!usbManager.hasPermission(usbDevice)) {
|
||||
mStatusView.setText("Need permission");
|
||||
rusEFI.requestUsbPermission(usbDevice, action);
|
||||
return null;
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Nullable
|
||||
public static AndroidSerial getAndroidSerial(rusEFI rusEFI, TextView mStatusView, UsbManager usbManager) {
|
||||
// todo: should support separate actions not default to dashboard!
|
||||
UsbSerialDriver driver = getSerialDriver(rusEFI, mStatusView, usbManager, PermissionGrantedAction.DASHBOARD);
|
||||
if (driver == null) {
|
||||
// error already reported to UI or permission request was fired
|
||||
return null;
|
||||
}
|
||||
UsbDeviceConnection connection = usbManager.openDevice(driver.getDevice());
|
||||
if (connection == null) {
|
||||
// add UsbManager.requestPermission(driver.getDevice(), ..) handling here
|
||||
|
|
|
@ -53,6 +53,13 @@
|
|||
android:onClick="sendMessage"
|
||||
android:text="Sound" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonConnect"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onConnectButton"
|
||||
android:text="Connect" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonBroadcast"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -64,7 +71,7 @@
|
|||
android:id="@+id/broadcastStatus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView" />
|
||||
android:text="Hello rusEFI" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -36,7 +36,7 @@ public class AutoupdateUtil {
|
|||
JProgressBar jProgressBar = new JProgressBar();
|
||||
|
||||
frameHelper.getFrame().setTitle(title);
|
||||
jProgressBar.setMaximum(ConnectionAndMeta.STEPS);
|
||||
jProgressBar.setMaximum(ConnectionAndMeta.CENTUM);
|
||||
jProgressBarAtomicReference.set(jProgressBar);
|
||||
frameHelper.showFrame(jProgressBar, true);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public class ConnectionAndMeta {
|
|||
public static final String BASE_URL_LATEST = "https://rusefi.com/build_server/autoupdate/";
|
||||
|
||||
private static final int BUFFER_SIZE = 32 * 1024;
|
||||
public static final int STEPS = 1000;
|
||||
public static final int CENTUM = 100;
|
||||
private final String zipFileName;
|
||||
private HttpsURLConnection httpConnection;
|
||||
private long completeFileSize;
|
||||
|
@ -42,15 +42,13 @@ public class ConnectionAndMeta {
|
|||
downloadedFileSize += newDataSize;
|
||||
|
||||
// calculate progress
|
||||
final int currentProgress = (int) ((((double) downloadedFileSize) / ((double) completeFileSize)) * STEPS);
|
||||
|
||||
int currentPercentage = (int) (100L * downloadedFileSize / completeFileSize);
|
||||
int currentPercentage = (int) (CENTUM * downloadedFileSize / completeFileSize);
|
||||
if (currentPercentage > printedPercentage + 5) {
|
||||
System.out.println("Downloaded " + currentPercentage + "%");
|
||||
printedPercentage = currentPercentage;
|
||||
listener.onPercentage(currentPercentage);
|
||||
}
|
||||
|
||||
listener.onPercentage(currentProgress);
|
||||
|
||||
bout.write(data, 0, newDataSize);
|
||||
}
|
||||
|
@ -86,7 +84,7 @@ public class ConnectionAndMeta {
|
|||
}
|
||||
|
||||
public interface DownloadProgressListener {
|
||||
void onPercentage(int currentProgress);
|
||||
void onPercentage(int currentPercentage);
|
||||
}
|
||||
|
||||
private static class AcceptAnyCertificateTrustManager implements X509TrustManager {
|
||||
|
|
Loading…
Reference in New Issue