Remove async promise

pull/653/merge
Varun Patil 2023-05-08 13:25:44 -07:00
parent b23b1d81f6
commit 4aaacdda0d
4 changed files with 80 additions and 86 deletions

View File

@ -3,6 +3,7 @@ package gallery.memories;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@ -34,6 +35,14 @@ public class MainActivity extends AppCompatActivity {
view.loadUrl(request.getUrl().toString());
return false;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
if (request.getUrl().getHost().equals("127.0.0.1")) {
return mNativeX.handleRequest(request.getUrl().getPath());
}
return null;
}
});
WebSettings webSettings = binding.webview.getSettings();

View File

@ -5,29 +5,80 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.webkit.JavascriptInterface;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import androidx.collection.ArrayMap;
import java.io.ByteArrayInputStream;
import java.util.Map;
import gallery.memories.service.ImageService;
import gallery.memories.service.JsService;
import gallery.memories.service.TimelineQuery;
public class NativeX {
public static final String TAG = "NativeX";
Activity mActivity;
protected JsService mJsService;
protected ImageService mImageService;
protected TimelineQuery mQuery;
public NativeX(Activity activity, WebView webView) {
mActivity = activity;
mJsService = new JsService(activity, webView);
mImageService = new ImageService(activity);
mQuery = new TimelineQuery(activity);
}
public WebResourceResponse handleRequest(final String path) {
byte[] bytes = null;
String mimeType = "application/json";
try {
// Match the path using regex
String[] parts = path.split("/");
if (path.matches("^/image/preview/\\d+$")) {
// Preview Image
bytes = mImageService.getPreview(Long.parseLong(parts[3]));
mimeType = "image/jpeg";
} else if (path.matches("^/image/full/\\d+$")) {
// Full sized image
bytes = mImageService.getFull(Long.parseLong(parts[3]));
mimeType = "image/jpeg";
} else if (path.matches("^/api/days$")) {
// Days list
bytes = mQuery.getDays().toString().getBytes();
} else if (path.matches("/api/days/\\d+$")) {
// Single day photos
bytes = mQuery.getByDayId(Long.parseLong(parts[3])).toString().getBytes();
} else {
Log.e(TAG, "handleRequest: Unknown path: " + path);
}
} catch (Exception e) {
Log.e(TAG, "handleRequest: ", e);
}
// Construct the response
WebResourceResponse response;
if (bytes != null) {
response = new WebResourceResponse(mimeType, "UTF-8", new ByteArrayInputStream(bytes));
} else {
response = new WebResourceResponse(mimeType, "UTF-8", new ByteArrayInputStream("{}".getBytes()));
response.setStatusCodeAndReasonPhrase(500, "Internal Server Error");
}
// Allow CORS from all origins
Map<String, String> headers = new ArrayMap<>();
headers.put("Access-Control-Allow-Origin", "*");
response.setResponseHeaders(headers);
return response;
}
@JavascriptInterface
public boolean isNative() {
return true;
@ -49,19 +100,4 @@ public class NativeX {
window.getDecorView().setSystemUiVisibility(isDark ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
@JavascriptInterface
public void getLocalDays(final String call, final long _ignore) {
mJsService.runAsync(call, () -> mQuery.getDays().toString().getBytes());
}
@JavascriptInterface
public void getLocalByDayId(final String call, final long dayId) {
mJsService.runAsync(call, () -> mQuery.getByDayId(dayId).toString().getBytes());
}
@JavascriptInterface
public void getJpeg(final String call, final String uri) {
mJsService.runAsync(call, () -> mImageService.getFromURI(uri));
}
}

View File

@ -15,32 +15,9 @@ public class ImageService {
mCtx = context;
}
public byte[] getFromURI(String uri) throws Exception {
// URI looks like nativex://<type>/<id>
String[] parts = uri.split("/");
if (parts.length != 4) {
throw new Exception("Invalid URI path");
}
final String type = parts[2];
final long id = Long.parseLong(parts[3]);
Bitmap bitmap = null;
if (type.equals("preview")) {
bitmap = MediaStore.Images.Thumbnails.getThumbnail(
mCtx.getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
} else if (type.equals("full")) {
try {
bitmap = MediaStore.Images.Media.getBitmap(
mCtx.getContentResolver(), ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id));
} catch (IOException e) {
e.printStackTrace();
}
} else {
throw new Exception("Invalid request type");
}
public byte[] getPreview(final long id) throws Exception {
Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(
mCtx.getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
if (bitmap == null) {
throw new Exception("Thumbnail not found");
@ -50,4 +27,18 @@ public class ImageService {
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
return stream.toByteArray();
}
public byte[] getFull(final long id) throws Exception {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(
mCtx.getContentResolver(), ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id));
if (bitmap == null) {
throw new Exception("Image not found");
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
return stream.toByteArray();
}
}

View File

@ -1,42 +0,0 @@
package gallery.memories.service;
import android.app.Activity;
import android.webkit.WebView;
import java.util.Base64;
public class JsService {
protected Activity mActivity;
protected WebView mWebView;
public JsService(Activity activity, WebView webView) {
mActivity = activity;
mWebView = webView;
}
public interface AsyncFunction {
byte[] run() throws Exception;
}
public void runAsync(final String call, final AsyncFunction callable) {
new Thread(() -> {
try {
jsResolve(call, callable.run());
} catch (Exception e) {
jsReject(call, e);
}
}).start();
}
protected void jsResolve(String call, byte[] ret) {
final String b64 = Base64.getEncoder().encodeToString(ret);
mActivity.runOnUiThread(() -> mWebView.evaluateJavascript("window.nativexr('" + call + "', '" + b64 + "');", null));
}
protected void jsReject(String call, Exception e) {
String message = e.getMessage();
message = message == null ? "Unknown error occured" : message;
final String b64 = Base64.getEncoder().encodeToString(message.getBytes());
mActivity.runOnUiThread(() -> mWebView.evaluateJavascript("window.nativexr('" + call + "', undefined, '" + b64 + "');", null));
}
}