Android progress
This commit is contained in:
parent
eef4e05428
commit
88b3ef23fc
|
@ -30,8 +30,11 @@
|
||||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||||
android:resource="@xml/device_filter" />
|
android:resource="@xml/device_filter" />
|
||||||
</activity>
|
</activity>
|
||||||
|
<service android:name=".SerialService" />
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.rusefi.app;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Binder;
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
public class SerialService extends Service {
|
||||||
|
class SerialBinder extends Binder {
|
||||||
|
/*
|
||||||
|
SerialService getService() {
|
||||||
|
return SerialService.this;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private final IBinder binder = new SerialBinder();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return binder;
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ import com.devexperts.logging.Logging;
|
||||||
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
import com.google.android.material.snackbar.BaseTransientBottomBar;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.rusefi.Callable;
|
import com.rusefi.Callable;
|
||||||
|
import com.rusefi.Timeouts;
|
||||||
import com.rusefi.app.serial.AndroidSerial;
|
import com.rusefi.app.serial.AndroidSerial;
|
||||||
import com.rusefi.auth.AuthTokenUtil;
|
import com.rusefi.auth.AuthTokenUtil;
|
||||||
import com.rusefi.dfu.DfuConnection;
|
import com.rusefi.dfu.DfuConnection;
|
||||||
|
@ -57,6 +58,8 @@ import com.rusefi.io.serial.StreamConnector;
|
||||||
import com.rusefi.proxy.NetworkConnector;
|
import com.rusefi.proxy.NetworkConnector;
|
||||||
import com.rusefi.proxy.NetworkConnectorContext;
|
import com.rusefi.proxy.NetworkConnectorContext;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
public class rusEFI extends Activity {
|
public class rusEFI extends Activity {
|
||||||
private final static Logging log = Logging.getLogging(rusEFI.class);
|
private final static Logging log = Logging.getLogging(rusEFI.class);
|
||||||
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
|
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
|
||||||
|
@ -66,11 +69,12 @@ public class rusEFI extends Activity {
|
||||||
//
|
//
|
||||||
// protected static final int DFU_DETACH_TIMEOUT = 1000;
|
// protected static final int DFU_DETACH_TIMEOUT = 1000;
|
||||||
|
|
||||||
private static final String VERSION = "rusEFI app v0.0000007\n";
|
private static final String VERSION = "rusEFI app v0.0000008\n";
|
||||||
|
|
||||||
/* UI elements */
|
/* UI elements */
|
||||||
private TextView mStatusView;
|
private TextView mStatusView;
|
||||||
private TextView mResultView;
|
private TextView mResultView;
|
||||||
|
private TextView broadcastStatus;
|
||||||
private EditText authToken;
|
private EditText authToken;
|
||||||
private TextView authStatusMessage;
|
private TextView authStatusMessage;
|
||||||
private TextView authStatusClickableUrl;
|
private TextView authStatusClickableUrl;
|
||||||
|
@ -87,9 +91,16 @@ public class rusEFI extends Activity {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_usb);
|
setContentView(R.layout.activity_usb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to make sure that WiFi is available for us, this might be related to screen on?
|
||||||
|
*/
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
findViewById(R.id.buttonSound).setVisibility(View.GONE);
|
findViewById(R.id.buttonSound).setVisibility(View.GONE);
|
||||||
findViewById(R.id.buttonDfu).setVisibility(View.GONE);
|
findViewById(R.id.buttonDfu).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
broadcastStatus = findViewById(R.id.broadcastStatus);
|
||||||
|
|
||||||
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||||
|
|
||||||
// turn on scree while ADB debugging idle phone
|
// turn on scree while ADB debugging idle phone
|
||||||
|
@ -244,6 +255,8 @@ public class rusEFI extends Activity {
|
||||||
} else if (view.getId() == R.id.buttonSound) {
|
} else if (view.getId() == R.id.buttonSound) {
|
||||||
soundBroadcast.start();
|
soundBroadcast.start();
|
||||||
} else if (view.getId() == R.id.buttonBroadcast) {
|
} else if (view.getId() == R.id.buttonBroadcast) {
|
||||||
|
startService(new Intent(this, SerialService.class));
|
||||||
|
|
||||||
AndroidSerial serial = AndroidSerial.getAndroidSerial(mStatusView, mResultView, usbManager);
|
AndroidSerial serial = AndroidSerial.getAndroidSerial(mStatusView, mResultView, usbManager);
|
||||||
if (serial == null) {
|
if (serial == null) {
|
||||||
// error already reported to mStatusView
|
// error already reported to mStatusView
|
||||||
|
@ -262,18 +275,30 @@ public class rusEFI extends Activity {
|
||||||
linkManager.getConnector().connectAndReadConfiguration(new ConnectionStateListener() {
|
linkManager.getConnector().connectAndReadConfiguration(new ConnectionStateListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionEstablished() {
|
public void onConnectionEstablished() {
|
||||||
mResultView.post(() -> mResultView.append("On connection established\n"));
|
mResultView.post(() -> mResultView.append(new Date() + " On connection established\n"));
|
||||||
|
|
||||||
NetworkConnectorContext context = new NetworkConnectorContext();
|
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) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
previousTime = now;
|
||||||
|
broadcastStatus.post(() -> broadcastStatus.setText(targetEcuSocket.getBytesIn() + "/" + targetEcuSocket.getBytesOut()));
|
||||||
|
}
|
||||||
|
};
|
||||||
NetworkConnector.NetworkConnectorResult result = new NetworkConnector().start(NetworkConnector.Implementation.Android,
|
NetworkConnector.NetworkConnectorResult result = new NetworkConnector().start(NetworkConnector.Implementation.Android,
|
||||||
getAuthToken(), context, new NetworkConnector.ReconnectListener() {
|
getAuthToken(), context, new NetworkConnector.ReconnectListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onReconnect() {
|
public void onReconnect() {
|
||||||
|
}
|
||||||
|
}, linkManager, oncePerSecondStatistics);
|
||||||
|
|
||||||
}
|
mResultView.post(() -> mResultView.append(new Date() + " Broadcast: " + result + "\n"));
|
||||||
}, linkManager);
|
|
||||||
|
|
||||||
mResultView.post(() -> mResultView.append("Broadcast: " + result + "\n"));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,12 @@
|
||||||
android:onClick="sendMessage"
|
android:onClick="sendMessage"
|
||||||
android:text="Broadcast" />
|
android:text="Broadcast" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/broadcastStatus"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="TextView" />
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
# Implementation Details
|
||||||
|
|
||||||
|
USB serial
|
||||||
|
https://github.com/mik3y/usb-serial-for-android
|
||||||
|
|
||||||
|
DFU implementation
|
||||||
|
https://github.com/rusefi/dfu_java
|
||||||
|
|
||||||
|
Error reporting uses
|
||||||
|
https://github.com/ACRA/acra
|
||||||
|
|
||||||
|
Hex reader based on
|
||||||
|
https://github.com/encedo/hex2dfu
|
|
@ -67,10 +67,10 @@ public class NetworkConnector implements Closeable {
|
||||||
return NetworkConnectorResult.ERROR;
|
return NetworkConnectorResult.ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return start(implementation, authToken, context, reconnectListener, controllerConnector);
|
return start(implementation, authToken, context, reconnectListener, controllerConnector, ActivityListener.VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkConnectorResult start(Implementation implementation, String authToken, NetworkConnectorContext context, ReconnectListener reconnectListener, LinkManager linkManager) {
|
public NetworkConnectorResult start(Implementation implementation, String authToken, NetworkConnectorContext context, ReconnectListener reconnectListener, LinkManager linkManager, ActivityListener activityListener) {
|
||||||
ControllerInfo controllerInfo;
|
ControllerInfo controllerInfo;
|
||||||
try {
|
try {
|
||||||
controllerInfo = getControllerInfo(linkManager, linkManager.getConnector().getBinaryProtocol().getStream());
|
controllerInfo = getControllerInfo(linkManager, linkManager.getConnector().getBinaryProtocol().getStream());
|
||||||
|
@ -88,6 +88,7 @@ public class NetworkConnector implements Closeable {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
start(implementation,
|
start(implementation,
|
||||||
|
activityListener,
|
||||||
context.serverPortForControllers(), linkManager, authToken, (String message) -> {
|
context.serverPortForControllers(), linkManager, authToken, (String message) -> {
|
||||||
log.error(message + " Disconnect from proxy server detected, now sleeping " + context.reconnectDelay() + " seconds");
|
log.error(message + " Disconnect from proxy server detected, now sleeping " + context.reconnectDelay() + " seconds");
|
||||||
sleep(context.reconnectDelay() * Timeouts.SECOND);
|
sleep(context.reconnectDelay() * Timeouts.SECOND);
|
||||||
|
@ -108,7 +109,7 @@ public class NetworkConnector implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static SessionDetails start(Implementation implementation, int serverPortForControllers, LinkManager linkManager, String authToken, final TcpIoStream.DisconnectListener disconnectListener, int oneTimeToken, ControllerInfo controllerInfo, final NetworkConnectorContext context) throws IOException {
|
private static SessionDetails start(Implementation implementation, ActivityListener activityListener, int serverPortForControllers, LinkManager linkManager, String authToken, final TcpIoStream.DisconnectListener disconnectListener, int oneTimeToken, ControllerInfo controllerInfo, final NetworkConnectorContext context) throws IOException {
|
||||||
IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream();
|
IoStream targetEcuSocket = linkManager.getConnector().getBinaryProtocol().getStream();
|
||||||
|
|
||||||
SessionDetails deviceSessionDetails = new SessionDetails(implementation, controllerInfo, authToken, oneTimeToken, rusEFIVersion.CONSOLE_VERSION);
|
SessionDetails deviceSessionDetails = new SessionDetails(implementation, controllerInfo, authToken, oneTimeToken, rusEFIVersion.CONSOLE_VERSION);
|
||||||
|
@ -146,6 +147,7 @@ public class NetworkConnector implements Closeable {
|
||||||
BinaryProtocolServer.Packet response = targetEcuSocket.readPacket();
|
BinaryProtocolServer.Packet response = targetEcuSocket.readPacket();
|
||||||
log.info("Relaying response to proxy size=" + response.getPacket().length);
|
log.info("Relaying response to proxy size=" + response.getPacket().length);
|
||||||
stream.sendPacket(response);
|
stream.sendPacket(response);
|
||||||
|
activityListener.onActivity(targetEcuSocket);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
baseBroadcastingThread.start();
|
baseBroadcastingThread.start();
|
||||||
|
@ -209,6 +211,16 @@ public class NetworkConnector implements Closeable {
|
||||||
void onReconnect();
|
void onReconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ActivityListener {
|
||||||
|
ActivityListener VOID = new ActivityListener() {
|
||||||
|
@Override
|
||||||
|
public void onActivity(IoStream targetEcuSocket) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
void onActivity(IoStream targetEcuSocket);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Implementation {
|
public enum Implementation {
|
||||||
Android,
|
Android,
|
||||||
Plugin,
|
Plugin,
|
||||||
|
|
Loading…
Reference in New Issue