mirror of
https://github.com/beemdevelopment/Aegis
synced 2024-09-06 16:03:30 +00:00
Add tests for scanning QR codes
This commit is contained in:
parent
3b715d58cf
commit
5f12eae678
|
@ -2,8 +2,6 @@ package com.beemdevelopment.aegis.helpers;
|
||||||
|
|
||||||
import static android.graphics.ImageFormat.YUV_420_888;
|
import static android.graphics.ImageFormat.YUV_420_888;
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ public class QrCodeAnalyzer implements ImageAnalysis.Analyzer {
|
||||||
|
|
||||||
Result result = reader.decode(bitmap, hints);
|
Result result = reader.decode(bitmap, hints);
|
||||||
if (_listener != null) {
|
if (_listener != null) {
|
||||||
new Handler(Looper.getMainLooper()).post(() -> _listener.onQrCodeDetected(result));
|
_listener.onQrCodeDetected(result);
|
||||||
}
|
}
|
||||||
} catch (NotFoundException ignored) {
|
} catch (NotFoundException ignored) {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.beemdevelopment.aegis.ui;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
@ -170,23 +171,25 @@ public class ScannerActivity extends AegisActivity implements QrCodeAnalyzer.Lis
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onQrCodeDetected(Result result) {
|
public void onQrCodeDetected(Result result) {
|
||||||
if (_analysis != null) {
|
new Handler(getMainLooper()).post(() -> {
|
||||||
try {
|
if (_analysis != null) {
|
||||||
Uri uri = Uri.parse(result.getText().trim());
|
try {
|
||||||
if (uri.getScheme() != null && uri.getScheme().equals(GoogleAuthInfo.SCHEME_EXPORT)) {
|
Uri uri = Uri.parse(result.getText().trim());
|
||||||
handleExportUri(uri);
|
if (uri.getScheme() != null && uri.getScheme().equals(GoogleAuthInfo.SCHEME_EXPORT)) {
|
||||||
} else {
|
handleExportUri(uri);
|
||||||
handleUri(uri);
|
} else {
|
||||||
}
|
handleUri(uri);
|
||||||
} catch (GoogleAuthInfoException e) {
|
}
|
||||||
e.printStackTrace();
|
} catch (GoogleAuthInfoException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
unbindPreview(_cameraProvider);
|
unbindPreview(_cameraProvider);
|
||||||
Dialogs.showErrorDialog(this,
|
Dialogs.showErrorDialog(this,
|
||||||
e.isPhoneFactor() ? R.string.read_qr_error_phonefactor : R.string.read_qr_error,
|
e.isPhoneFactor() ? R.string.read_qr_error_phonefactor : R.string.read_qr_error,
|
||||||
e, ((dialog, which) -> bindPreview(_cameraProvider)));
|
e, ((dialog, which) -> bindPreview(_cameraProvider)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleUri(Uri uri) throws GoogleAuthInfoException {
|
private void handleUri(Uri uri) throws GoogleAuthInfoException {
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
package com.beemdevelopment.aegis.helpers;
|
||||||
|
|
||||||
|
import static android.graphics.ImageFormat.YUV_420_888;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.media.Image;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.camera.core.ImageInfo;
|
||||||
|
import androidx.camera.core.ImageProxy;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.util.IOUtils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class QrCodeAnalyzerTest {
|
||||||
|
private static final String _expectedUri = "otpauth://totp/neo4j:Charlotte?secret=B33WS2ALPT34K4BNY24AYROE4M&issuer=neo4j&algorithm=SHA1&digits=6&period=30";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScanQrCode() {
|
||||||
|
boolean found = scan("qr.y.gz", 1600, 1200, 1600);
|
||||||
|
assertTrue("QR code not found", found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScanStridedQrCode() {
|
||||||
|
boolean found = scan("qr.strided.y.gz", 1840, 1380, 1840);
|
||||||
|
assertFalse("QR code found", found);
|
||||||
|
|
||||||
|
found = scan("qr.strided.y.gz", 1840, 1380, 1856);
|
||||||
|
assertTrue("QR code not found", found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean scan(String fileName, int width, int height, int rowStride) {
|
||||||
|
AtomicBoolean found = new AtomicBoolean();
|
||||||
|
QrCodeAnalyzer analyzer = new QrCodeAnalyzer(result -> {
|
||||||
|
assertEquals(_expectedUri, result.getText());
|
||||||
|
found.set(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
FakeImageProxy imgProxy;
|
||||||
|
try (InputStream inStream = getClass().getResourceAsStream(fileName);
|
||||||
|
GZIPInputStream zipStream = new GZIPInputStream(inStream)) {
|
||||||
|
imgProxy = new FakeImageProxy(IOUtils.readAll(zipStream), width, height, rowStride);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzer.analyze(imgProxy);
|
||||||
|
return found.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FakePlaneProxy implements ImageProxy.PlaneProxy {
|
||||||
|
private final byte[] _y;
|
||||||
|
private final int _rowStride;
|
||||||
|
|
||||||
|
public FakePlaneProxy(byte[] y, int rowStride) {
|
||||||
|
_y = y;
|
||||||
|
_rowStride = rowStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowStride() {
|
||||||
|
return _rowStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPixelStride() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ByteBuffer getBuffer() {
|
||||||
|
return ByteBuffer.wrap(_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FakeImageProxy implements ImageProxy {
|
||||||
|
private final byte[] _y;
|
||||||
|
private final int _width;
|
||||||
|
private final int _height;
|
||||||
|
private final int _rowStride;
|
||||||
|
|
||||||
|
public FakeImageProxy(byte[] y, int width, int height, int rowStride) {
|
||||||
|
_y = y;
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
_rowStride = rowStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Rect getCropRect() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCropRect(@Nullable @org.jetbrains.annotations.Nullable Rect rect) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFormat() {
|
||||||
|
return YUV_420_888;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
|
return _width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ImageProxy.PlaneProxy[] getPlanes() {
|
||||||
|
return new PlaneProxy[]{new FakePlaneProxy(_y, _rowStride)};
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ImageInfo getImageInfo() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Image getImage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
BIN
app/src/test/resources/com/beemdevelopment/aegis/helpers/qr.y.gz
Normal file
BIN
app/src/test/resources/com/beemdevelopment/aegis/helpers/qr.y.gz
Normal file
Binary file not shown.
Loading…
Reference in a new issue