Skip to content

Commit

Permalink
Iron out networking bugs
Browse files Browse the repository at this point in the history
- Detect when we aren't connected to a Fuji network (WiFi access not available)
- Fix broken socket bugs after first connection
- Add ram-cache thumbnail loading (it's still slow!) And if I try to cache textures,
we will easily get OOM after a few thumbnails.
- Tested X-T20 vusb & X-A2
  • Loading branch information
petabyt committed Sep 1, 2023
1 parent 0bd6b62 commit 5fa201f
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 88 deletions.
1 change: 1 addition & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions app/src/main/java/dev/danielc/fujiapp/Backend.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public static void reportError(int code, String reason) {
if (wifi.killSwitch == false) {
wifi.killSwitch = true;

print("Safely killed connection: " + code);
print("Safely killed connection: " + code + "\n");
if (reason != null) {
print("Reason: " + reason);
print("Reason: " + reason + "\n");
}

Backend.wifi.close();
Expand All @@ -51,8 +51,8 @@ public static void reportError(int code, String reason) {
// In order to give the backend access to the static methods, new objects must be made
private static boolean haveInited = false;
public static void init() {
wifi = new WiFiComm();
if (haveInited == false) {
wifi = new WiFiComm();
cInit(new Backend(), wifi);
}
haveInited = true;
Expand All @@ -64,12 +64,13 @@ public static void clear() {
}

// Constants
public static final String FUJI_IP = "192.168.1.33";
//public static final String FUJI_IP = "192.168.0.1";
//public static final String FUJI_IP = "192.168.1.33";
public static final String FUJI_IP = "192.168.0.1";
public static final int FUJI_CMD_PORT = 55740;
public static final int FUJI_EVENT_PORT = 55741;
public static final int FUJI_VIDEO_PORT = 55742;
public static final int TIMEOUT = 1000;
public static final int OPEN_TIMEOUT = 1000;
public static final int TIMEOUT = 2000;
public static final int PTP_OF_JPEG = 0x3801;

// Note: 'synchronized' means only one of these methods can be used at time -
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/dev/danielc/fujiapp/Camera.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public static JSONObject openSession() throws Exception {
return Backend.run("ptp_open_session");
}

public static JSONObject closeSession() throws Exception {
return Backend.run("ptp_close_session");
}

public static JSONObject getObjectInfo(int handle) throws Exception {
JSONObject jsonObject = Backend.run("ptp_get_object_info", new int[]{handle});
return jsonObject;
Expand Down
17 changes: 14 additions & 3 deletions app/src/main/java/dev/danielc/fujiapp/Gallery.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ protected void onCreate(Bundle savedInstanceState) {
findViewById(R.id.disconnectButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Backend.reportError(Backend.PTP_OK, "Graceful disconnect\n");
if (Backend.wifi.killSwitch) {
Intent intent = new Intent(Gallery.this, MainActivity.class);
startActivity(intent);
} else {
Backend.reportError(Backend.PTP_OK, "Graceful disconnect\n");
}
}
});

Expand All @@ -83,6 +88,7 @@ public void run() {
Backend.print("Initialized connection.\n");
} else {
Backend.print("Failed to init socket\n");
Backend.reportError(Backend.PTP_IO_ERR, "Graceful disconnect\n");
return;
}

Expand All @@ -97,6 +103,7 @@ public void run() {
Camera.openSession();
} catch (Exception e) {
Backend.print("Failed to open session.\n");
Backend.reportError(Backend.PTP_IO_ERR, "Graceful disconnect\n");
return;
}

Expand All @@ -105,12 +112,14 @@ public void run() {
Backend.print("Gained access to device.\n");
} else {
Backend.print("Failed to gain access to device.");
Backend.reportError(Backend.PTP_IO_ERR, "Graceful disconnect\n");
return;
}

// Camera mode must be set before anything else
if (Backend.cFujiConfigInitMode() != 0) {
Backend.print("Failed to configure mode with the camera.\n");
Backend.reportError(Backend.PTP_IO_ERR, "Graceful disconnect\n");
return;
}

Expand All @@ -120,8 +129,10 @@ public void run() {
showWarning("This camera is untested, don't expect it to work.");
}

Backend.print("Configuring versions and stuff..\n");
if (Backend.cFujiConfigVersion() != 0) {
Backend.print("Failed to configure camera function version.\n");
Backend.print("Failed to configure camera versions.\n");
Backend.reportError(Backend.PTP_IO_ERR, "Graceful disconnect\n");
return;
}

Expand Down Expand Up @@ -155,7 +166,7 @@ public void run() {
startActivity(intent);
// TODO: Choose between these two?
Toast.makeText(Gallery.this, "Failed to ping, disconnected", Toast.LENGTH_SHORT).show();
Backend.print("Disconnected.\n");
Backend.reportError(Backend.PTP_IO_ERR, "Failed to ping camera\n");
}
});
return;
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/dev/danielc/fujiapp/ImageAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ public void run() {
} else if (jpegByteArray.length == 0) {
// Unable to find thumbnail - assume it's a folder or non-jpeg
holder.itemView.setOnClickListener(null);
Backend.print("Failed to get image #" + id + "\n");
// TODO: reset the image to unknown or default
// Maybe run getobjinfo to see what it is
return;
}
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.length);
if (bitmap == null) {
Backend.print("Image decode error\n");
return;
}
holder.itemView.post(new Runnable() {
@Override
Expand All @@ -74,6 +77,7 @@ public void run() {
});
} catch (OutOfMemoryError e) {
Backend.print("Out of memory\n");
return;
}
}
}).start();
Expand Down
22 changes: 13 additions & 9 deletions app/src/main/java/dev/danielc/fujiapp/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,19 @@ public void connectClick(View v) {
return;
}


if (Backend.wifi.fujiConnectToCmd((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE))) {
Backend.print("Failed to connect\n");
} else {
Backend.print("Connection success\n");
Backend.logLocation = "gallery";
Intent intent = new Intent(MainActivity.this, Gallery.class);
startActivity(intent);
}
new Thread(new Runnable() {
@Override
public void run() {
if (Backend.wifi.fujiConnectToCmd((ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE))) {
Backend.print("Failed to connect\n");
} else {
Backend.print("Connection success\n");
Backend.logLocation = "gallery";
Intent intent = new Intent(MainActivity.this, Gallery.class);
startActivity(intent);
}
}
}).start();
}

public static MainActivity getInstance() {
Expand Down
58 changes: 58 additions & 0 deletions app/src/main/java/dev/danielc/fujiapp/Tester.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import android.os.Handler;
import android.os.Build;

import java.net.Socket;
import java.net.SocketTimeoutException;

public class Tester extends AppCompatActivity {
private Handler handler;

Expand Down Expand Up @@ -46,6 +49,55 @@ private void connectBluetooth() {
}
}

Socket testSock = null;
void socketTest(ConnectivityManager m) {
try {
NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.e("sad", "Wifi available");
ConnectivityManager.setProcessDefaultNetwork(network);

try {
Socket s = new Socket(Backend.FUJI_IP, Backend.FUJI_CMD_PORT);
s.setKeepAlive(true);
s.setTcpNoDelay(true);
s.setReuseAddress(true);
testSock = s;
log("Success socket");
} catch (Exception e) {
fail(e.toString());
}

m.unregisterNetworkCallback(this);
}
};

if (Build.VERSION.SDK_INT >= 26) {
m.requestNetwork(requestBuilder.build(), networkCallback, Backend.OPEN_TIMEOUT);
} else {
m.requestNetwork(requestBuilder.build(), networkCallback);
}
} catch (Exception e) {
fail(e.toString());
}

try {
Thread.sleep(1000);
if (testSock != null) {
byte[] data = {12, 12, 12, 12};
testSock.getOutputStream().write(data);
testSock.getOutputStream().flush();

testSock.close();
}
} catch (Exception e) {
fail(e.toString());
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -124,5 +176,11 @@ public void mainTest(ConnectivityManager m) {

rc = Backend.cFujiTestSetupImageGallery();
if (rc != 0) return;

try {
Camera.closeSession();
} catch (Exception e) {
fail("Failed to close session");
}
}
}
11 changes: 8 additions & 3 deletions app/src/main/java/dev/danielc/fujiapp/Viewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.StrictMode;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
Expand Down Expand Up @@ -178,10 +179,14 @@ public void run() {
bitmap = BitmapFactory.decodeByteArray(file, 0, file.length);
if (bitmap.getWidth() > GL10.GL_MAX_TEXTURE_SIZE) {
float ratio = ((float) bitmap.getHeight()) / ((float) bitmap.getWidth());
bitmap = Bitmap.createScaledBitmap(bitmap,
(int)(4096),
(int)((4096) * ratio),
// Will result in ~11mb tex, can do 4096, but uses 40ish megs, sometimes Android compains about OOM
// Might be able to increase for newer Androids
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap,
(int)(2048),
(int)((2048) * ratio),
false);
bitmap.recycle();
bitmap = newBitmap;
}

inProgress = false;
Expand Down
Loading

0 comments on commit 5fa201f

Please sign in to comment.