Merge branch 'master' into '1-patch-master'

# Conflicts:
#   .idea/assetWizardSettings.xml
#   .idea/modules.xml
#   app/build.gradle
#   app/src/main/AndroidManifest.xml
#   app/src/main/res/layout/activity_main.xml
#   app/src/main/res/values/colors.xml
#   app/src/main/res/values/strings.xml
#   app/src/main/res/values/styles.xml
#   build.gradle
#   gradle.properties
#   gradle/wrapper/gradle-wrapper.properties
pull/5/head
Felix Prahl-Kamps 2018-04-22 02:00:45 +02:00
commit 80b58bc77f
22 changed files with 774 additions and 2 deletions

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -0,0 +1,26 @@
package de.korrelator.overview.mispauth;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("de.korrelator.overview.mispauth", appContext.getPackageName());
}
}

View File

@ -0,0 +1,109 @@
package de.korrelator.overview.mispauth;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
*/
public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
private AppCompatDelegate mDelegate;
@Override
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getDelegate().onPostCreate(savedInstanceState);
}
public ActionBar getSupportActionBar() {
return getDelegate().getSupportActionBar();
}
public void setSupportActionBar(@Nullable Toolbar toolbar) {
getDelegate().setSupportActionBar(toolbar);
}
@Override
public MenuInflater getMenuInflater() {
return getDelegate().getMenuInflater();
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
@Override
public void setContentView(View view) {
getDelegate().setContentView(view);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().setContentView(view, params);
}
@Override
public void addContentView(View view, ViewGroup.LayoutParams params) {
getDelegate().addContentView(view, params);
}
@Override
protected void onPostResume() {
super.onPostResume();
getDelegate().onPostResume();
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
getDelegate().setTitle(title);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
getDelegate().onConfigurationChanged(newConfig);
}
@Override
protected void onStop() {
super.onStop();
getDelegate().onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
getDelegate().onDestroy();
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
private AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, null);
}
return mDelegate;
}
}

View File

@ -0,0 +1,45 @@
package de.korrelator.overview.mispauth;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Display;
import android.widget.ImageView;
import net.glxn.qrgen.android.QRCode;
import java.util.UUID;
public class GenerateQrActivity extends AppCompatActivity {
private Point displaySize;
private ImageView qrImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setHomeButtonEnabled(true);
setContentView(R.layout.activity_generate_qr);
qrImageView = findViewById(R.id.image_view_qr);
Display display = getWindowManager().getDefaultDisplay();
displaySize = new Point();
display.getSize(displaySize);
DisplayQR("https://www.google.de \n OrgName \n " + UUID.randomUUID());
}
public void DisplayQR(String message){
Bitmap bitmap = QRCode.from(message)
.withSize(displaySize.x, displaySize.y)
.withColor(0xFF000000, 0x00000000)
.bitmap();
qrImageView.setImageBitmap(bitmap);
}
}

View File

@ -0,0 +1,86 @@
package de.korrelator.overview.mispauth;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static final int QR_REQUEST_CODE = 123;
private TextView qrResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
qrResult = findViewById(R.id.text_view_qr_result);
Button scanButton = findViewById(R.id.button_scan);
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCameraIntent();
}
});
Button generateButton = findViewById(R.id.button_generate);
generateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startQrIntent();
}
});
}
private void startCameraIntent(){
Intent intent = new Intent(this, ReadQrActivity.class);
startActivityForResult(intent, QR_REQUEST_CODE);
}
private void startQrIntent(){
Intent intent = new Intent(this, GenerateQrActivity.class);
startActivity(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == QR_REQUEST_CODE) {
if(resultCode == Activity.RESULT_OK){
String result = data.getStringExtra("result");
qrResult.setText(result);
}
if (resultCode == Activity.RESULT_CANCELED) {
qrResult.setText("NO QR FOUND");
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -0,0 +1,346 @@
package de.korrelator.overview.mispauth;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.Size;
import android.util.SparseArray;
import android.view.Surface;
import android.view.TextureView;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.util.Arrays;
public class ReadQrActivity extends AppCompatActivity {
// CAMERA
private static final int CAMERA_REQUEST_CODE = 1;
private CameraManager cameraManager;
private int cameraFacing;
private String cameraId;
private Size previewSize;
private CameraDevice cameraDevice;
private CameraDevice.StateCallback stateCallback;
private CameraCaptureSession cameraCaptureSession;
private CaptureRequest captureRequest;
private CaptureRequest.Builder captureRequestBuilder;
private TextureView texturePreviewView;
private TextureView.SurfaceTextureListener surfaceTextureListener;
private HandlerThread camBackgroundThread;
private Handler camBackgroundHandler;
private ImageReader previewImageReader;
private ImageReader.OnImageAvailableListener previewImageListener;
// BARCODE
private BarcodeDetector barcodeDetector;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read_qr);
Initialize();
}
private void Initialize(){
texturePreviewView = findViewById(R.id.texture_view);
setUpBarcodeDetector();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
cameraFacing = CameraCharacteristics.LENS_FACING_BACK;
surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
setUpCamera();
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
ReadQrActivity.this.cameraDevice = cameraDevice;
createPreviewSession();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
cameraDevice.close();
ReadQrActivity.this.cameraDevice = null;
}
@Override
public void onError(CameraDevice cameraDevice, int error) {
cameraDevice.close();
ReadQrActivity.this.cameraDevice = null;
}
};
previewImageListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image img = reader.acquireLatestImage();
if(img == null){
return;
}
Bitmap bitmapImage = YUV_420_888_toRGBIntrinsics(img);
if(bitmapImage != null){
Frame frame = new Frame.Builder().setBitmap(bitmapImage).build();
SparseArray<Barcode> barcodes = barcodeDetector.detect(frame);
if(barcodes.size() > 0){
returnQrResult(barcodes.valueAt(0).displayValue);
}
}
img.close();
}
};
}
private void returnQrResult(String msg){
Intent returnIntent = new Intent();
returnIntent.putExtra("result", msg);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
private void setUpBarcodeDetector(){
barcodeDetector = new BarcodeDetector.Builder(getApplicationContext())
.setBarcodeFormats(Barcode.DATA_MATRIX | Barcode.QR_CODE)
.build();
Log.i("QR", "Setting up BarCodeDetector!");
if (!barcodeDetector.isOperational()) {
Log.e("QR", "BARCODE DETECTOR IS NOT OPERATIONAL !!!!");
}
}
private void setUpCamera() {
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == cameraFacing) {
StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewSize = streamConfigurationMap.getOutputSizes(SurfaceTexture.class)[0];
this.cameraId = cameraId;
// TEST
previewImageReader = ImageReader.newInstance(400, 600, ImageFormat.YUV_420_888, 2);
previewImageReader.setOnImageAvailableListener(previewImageListener, camBackgroundHandler);
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void openCamera() {
try {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(cameraId, stateCallback, camBackgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createPreviewSession() {
try {
SurfaceTexture surfaceTexture = texturePreviewView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// This is the real surface used for preview
captureRequestBuilder.addTarget(previewSurface);
// preview Surface for postprocessing
captureRequestBuilder.addTarget(previewImageReader.getSurface());
cameraDevice.createCaptureSession(Arrays.asList(previewSurface, previewImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
if (cameraDevice == null) {
return;
}
try {
captureRequest = captureRequestBuilder.build();
ReadQrActivity.this.cameraCaptureSession = cameraCaptureSession;
ReadQrActivity.this.cameraCaptureSession.setRepeatingRequest(captureRequest, null, camBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
}
}, camBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void camOpenBackgroundThread() {
camBackgroundThread = new HandlerThread("camera_background_thread");
camBackgroundThread.start();
camBackgroundHandler = new Handler(camBackgroundThread.getLooper());
}
private void closeCamera() {
if (cameraCaptureSession != null) {
cameraCaptureSession.close();
cameraCaptureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private void closeBackgroundThreads() {
if (camBackgroundHandler != null) {
camBackgroundThread.quitSafely();
camBackgroundThread = null;
camBackgroundHandler = null;
}
}
@Override
protected void onResume() {
super.onResume();
camOpenBackgroundThread();
if (texturePreviewView.isAvailable()) {
setUpCamera();
openCamera();
} else {
texturePreviewView.setSurfaceTextureListener(surfaceTextureListener);
}
}
@Override
protected void onStop() {
super.onStop();
closeCamera();
closeBackgroundThreads();
}
private Bitmap YUV_420_888_toRGBIntrinsics(Image image) {
if (image == null) return null;
int W = image.getWidth();
int H = image.getHeight();
Image.Plane Y = image.getPlanes()[0];
Image.Plane U = image.getPlanes()[1];
Image.Plane V = image.getPlanes()[2];
int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();
byte[] data = new byte[Yb + Ub + Vb];
Y.getBuffer().get(data, 0, Yb);
V.getBuffer().get(data, Yb, Vb);
U.getBuffer().get(data, Yb + Vb, Ub);
RenderScript rs = RenderScript.create(getApplicationContext());
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
in.copyFromUnchecked(data);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
out.copyTo(bmpout);
image.close();
return bmpout ;
}
}

View File

@ -0,0 +1,28 @@
package de.korrelator.overview.mispauth;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MainPreferenceFragment()).commit();
}
public static class MainPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_main);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" />
</vector>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GenerateQrActivity">
<ImageView
android:id="@+id/image_view_qr"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/AppTheme.NoActionBar">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="1dp">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/dividerVertical">
</View>
</LinearLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="Setttings"
android:icon="@drawable/ic_settings"
app:showAsAction="never" />
</menu>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorPrimary">#212121</color>
<color name="colorPrimaryDark">#000000</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="MISP Server Configuration">
<EditTextPreference
android:defaultValue="https://example.foo"
android:key="server_url"
android:summary="https://example.foo"
android:title="URL"/>
<EditTextPreference
android:defaultValue="Company Name"
android:key="company_name"
android:summary="Company XY"
android:title="Organization Name"/>
</PreferenceCategory>
<!--<PreferenceCategory android:layout="@layout/preference_divider"/>-->
<PreferenceCategory android:title="About">
<Preference
android:key="pref_static_field_key"
android:selectable="false"
android:persistent="false"
android:title="Version"
android:summary="0.0"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@ -0,0 +1,17 @@
package de.korrelator.overview.mispauth;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

2
readme.md Normal file
View File

@ -0,0 +1,2 @@
# MispAuth
Authentifizierung zweier Misp-Partner über QR-Codes