rewrite and rename SyncActivity -> ExchangeActivity

pull/5/head
Felix Prahl-Kamps 2019-07-02 23:40:42 +02:00
parent be88d0e3a5
commit a9498f45f1
12 changed files with 500 additions and 213 deletions

View File

@ -38,7 +38,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="lu.circl.mispbump">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="false"
@ -16,47 +15,43 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".activities.ExchangeActivity"></activity>
<activity android:name=".activities.SyncActivity2" />
<activity android:name=".activities.StartUpActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.LoginActivity"
android:label="@string/login"/>
android:label="@string/login" />
<activity
android:name=".activities.HomeActivity"
android:label="@string/app_name"/>
android:label="@string/app_name" />
<activity
android:name=".activities.SyncActivity"
android:configChanges="orientation|screenSize"
android:parentActivityName=".activities.HomeActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Translucent"/>
android:theme="@style/AppTheme.Translucent" />
<activity
android:name=".activities.UploadInfoActivity"
android:parentActivityName=".activities.HomeActivity"/>
android:parentActivityName=".activities.HomeActivity" />
<activity
android:name=".activities.UploadActivity"
android:configChanges="orientation|screenSize"
android:label="Upload"
android:parentActivityName=".activities.HomeActivity"/>
android:parentActivityName=".activities.HomeActivity" />
<activity
android:name=".activities.PreferenceActivity"
android:parentActivityName=".activities.HomeActivity"/>
android:parentActivityName=".activities.HomeActivity" />
<activity
android:name=".activities.ProfileActivity"
android:label="Profile"
android:parentActivityName=".activities.HomeActivity"
android:theme="@style/AppTheme.Translucent"/>
android:theme="@style/AppTheme.Translucent" />
</application>
</manifest>

View File

@ -0,0 +1,352 @@
package lu.circl.mispbump.activities;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.snackbar.Snackbar;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.List;
import lu.circl.mispbump.R;
import lu.circl.mispbump.auxiliary.DialogManager;
import lu.circl.mispbump.auxiliary.PreferenceManager;
import lu.circl.mispbump.auxiliary.QrCodeGenerator;
import lu.circl.mispbump.auxiliary.RandomString;
import lu.circl.mispbump.fragments.CameraFragment;
import lu.circl.mispbump.models.SyncInformation;
import lu.circl.mispbump.models.UploadInformation;
import lu.circl.mispbump.security.DiffieHellman;
public class ExchangeActivity extends AppCompatActivity {
private PreferenceManager preferenceManager;
private QrCodeGenerator qrCodeGenerator;
private DiffieHellman diffieHellman;
private UploadInformation uploadInformation;
private CameraFragment cameraFragment;
private CoordinatorLayout rootLayout;
private View qrFrame;
private TextView qrInfo;
private ImageView qrCode;
private ImageButton prevButton, nextButton;
private Bitmap publicKeyQr, dataQr;
private SyncState currentSyncState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync);
preferenceManager = PreferenceManager.getInstance(ExchangeActivity.this);
qrCodeGenerator = new QrCodeGenerator(ExchangeActivity.this);
diffieHellman = DiffieHellman.getInstance();
initViews();
initCamera();
uploadInformation = new UploadInformation();
publicKeyQr = generatePublicKeyBitmap();
dataQr = generateLocalSyncInfoBitmap();
setSyncState(SyncState.KEY_EXCHANGE);
}
private void initViews() {
rootLayout = findViewById(R.id.rootLayout);
qrFrame = findViewById(R.id.qrFrame);
qrCode = findViewById(R.id.qrCode);
qrInfo = findViewById(R.id.qrInfo);
prevButton = findViewById(R.id.prevButton);
prevButton.setOnClickListener(onPrevClicked());
nextButton = findViewById(R.id.nextButton);
nextButton.setOnClickListener(onNextClicked());
}
private void initCamera() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
cameraFragment = new CameraFragment();
cameraFragment.setOnQrAvailableListener(onQrScanned());
String fragmentTag = cameraFragment.getClass().getSimpleName();
fragmentTransaction.add(R.id.fragmentContainer, cameraFragment, fragmentTag);
fragmentTransaction.commit();
}
private Bitmap generatePublicKeyBitmap() {
return qrCodeGenerator.generateQrCode(DiffieHellman.publicKeyToString(diffieHellman.getPublicKey()));
}
private Bitmap generateLocalSyncInfoBitmap() {
uploadInformation.setLocal(generateLocalSyncInfo());
return qrCodeGenerator.generateQrCode(new Gson().toJson(uploadInformation.getLocal()));
}
private SyncInformation generateLocalSyncInfo() {
SyncInformation syncInformation = new SyncInformation();
syncInformation.organisation = preferenceManager.getUserOrganisation().toSyncOrganisation();
syncInformation.syncUserAuthkey = new RandomString(40).nextString();
syncInformation.baseUrl = preferenceManager.getServerUrl();
syncInformation.syncUserPassword = new RandomString(16).nextString();
syncInformation.syncUserEmail = preferenceManager.getUserInfo().email;
return syncInformation;
}
private void showQrCode(final Bitmap bitmap) {
runOnUiThread(new Runnable() {
@Override
public void run() {
qrCode.setImageBitmap(bitmap);
qrFrame.setVisibility(View.VISIBLE); // TODO animate
}
});
}
private void setSyncState(SyncState state) {
Log.d("DEBUG", "current sync state: " + state);
currentSyncState = state;
runOnUiThread(new Runnable() {
@Override
public void run() {
switch (currentSyncState) {
case KEY_EXCHANGE:
prevButton.setImageDrawable(getDrawable(R.drawable.ic_close));
prevButton.setVisibility(View.VISIBLE);
nextButton.setVisibility(View.GONE);
setCameraPreviewEnabled(true);
setReadQrStatus(ReadQrStatus.PENDING);
showQrCode(publicKeyQr);
break;
case KEY_EXCHANGE_DONE:
prevButton.setImageDrawable(getDrawable(R.drawable.ic_close));
prevButton.setVisibility(View.VISIBLE);
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
nextButton.setVisibility(View.VISIBLE);
setCameraPreviewEnabled(false);
setReadQrStatus(ReadQrStatus.SUCCESS);
showQrCode(publicKeyQr);
break;
case DATA_EXCHANGE:
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
prevButton.setVisibility(View.VISIBLE);
nextButton.setVisibility(View.GONE);
setCameraPreviewEnabled(true);
setReadQrStatus(ReadQrStatus.PENDING);
showQrCode(dataQr);
break;
case DATA_EXCHANGE_DONE:
prevButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_back));
prevButton.setVisibility(View.VISIBLE);
nextButton.setImageDrawable(getDrawable(R.drawable.ic_check));
nextButton.setVisibility(View.VISIBLE);
setCameraPreviewEnabled(false);
setReadQrStatus(ReadQrStatus.SUCCESS);
showQrCode(dataQr);
break;
}
}
});
}
private void setReadQrStatus(ReadQrStatus status) {
Log.d("DEBUG", "QR STATUS: " + status);
final Drawable drawable;
final int color;
switch (status) {
case PENDING:
drawable = getDrawable(R.drawable.ic_info_outline);
color = getColor(R.color.status_amber);
break;
case SUCCESS:
drawable = getDrawable(R.drawable.ic_check_outline);
color = getColor(R.color.status_green);
break;
case FAILURE:
drawable = getDrawable(R.drawable.ic_error_outline);
color = getColor(R.color.status_red);
break;
default:
drawable = getDrawable(R.drawable.ic_info_outline);
color = getColor(R.color.status_green);
break;
}
runOnUiThread(new Runnable() {
@Override
public void run() {
qrInfo.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
qrInfo.setCompoundDrawableTintList(ColorStateList.valueOf(color));
}
});
}
private void setCameraPreviewEnabled(boolean enabled) {
View view = findViewById(R.id.fragmentContainer);
if (enabled) {
Log.d("DEBUG", "cameraPreview enabled");
view.animate()
.alpha(1f)
.setDuration(250)
.start();
cameraFragment.setReadQrEnabled(true);
} else {
Log.d("DEBUG", "cameraPreview disabled");
view.animate()
.alpha(0f)
.setDuration(250)
.start();
cameraFragment.setReadQrEnabled(false);
}
}
private CameraFragment.QrScanCallback onQrScanned() {
return new CameraFragment.QrScanCallback() {
@Override
public void qrScanResult(String qrData) {
cameraFragment.setReadQrEnabled(false);
switch (currentSyncState) {
case KEY_EXCHANGE:
try {
diffieHellman.setForeignPublicKey(DiffieHellman.publicKeyFromString(qrData));
setSyncState(SyncState.KEY_EXCHANGE_DONE);
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
setReadQrStatus(ReadQrStatus.FAILURE);
cameraFragment.setReadQrEnabled(true);
Snackbar.make(rootLayout, "Public key not parsable", Snackbar.LENGTH_LONG).show();
}
break;
case DATA_EXCHANGE:
try {
final SyncInformation remoteSyncInfo = new Gson().fromJson(diffieHellman.decrypt(qrData), SyncInformation.class);
List<UploadInformation> uploadInformationList = preferenceManager.getUploadInformationList();
for (final UploadInformation ui : uploadInformationList) {
if (ui.getRemote().organisation.uuid.equals(remoteSyncInfo.organisation.uuid)) {
DialogManager.syncAlreadyExistsDialog(ui.getRemote(), remoteSyncInfo, ExchangeActivity.this, new DialogManager.IDialogFeedback() {
@Override
public void positive() {
// update remote info only
uploadInformation.setUuid(ui.getUuid());
uploadInformation.setDate();
}
@Override
public void negative() {
// replace credentials too
preferenceManager.removeUploadInformation(ui.getUuid());
}
});
break;
}
}
uploadInformation.setRemote(remoteSyncInfo);
preferenceManager.addUploadInformation(uploadInformation);
setSyncState(SyncState.DATA_EXCHANGE_DONE);
} catch (JsonSyntaxException e) {
setReadQrStatus(ReadQrStatus.FAILURE);
cameraFragment.setReadQrEnabled(true);
Snackbar.make(rootLayout, "Sync information not parsable", Snackbar.LENGTH_LONG).show();
}
break;
}
}
};
}
private View.OnClickListener onPrevClicked() {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (currentSyncState) {
case KEY_EXCHANGE:
case KEY_EXCHANGE_DONE:
// TODO warning that sync will be lost
finish();
break;
case DATA_EXCHANGE:
case DATA_EXCHANGE_DONE:
setSyncState(SyncState.KEY_EXCHANGE_DONE);
break;
}
}
};
}
private View.OnClickListener onNextClicked() {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (currentSyncState) {
case KEY_EXCHANGE_DONE:
setSyncState(SyncState.DATA_EXCHANGE);
break;
case DATA_EXCHANGE_DONE:
uploadInformation.setCurrentSyncStatus(UploadInformation.SyncStatus.PENDING);
preferenceManager.addUploadInformation(uploadInformation);
Intent i = new Intent(ExchangeActivity.this, UploadInfoActivity.class);
i.putExtra(UploadInfoActivity.EXTRA_UPLOAD_INFO_UUID, uploadInformation.getUuid());
startActivity(i);
finish();
break;
}
}
};
}
private enum SyncState {
KEY_EXCHANGE,
KEY_EXCHANGE_DONE,
DATA_EXCHANGE,
DATA_EXCHANGE_DONE
}
private enum ReadQrStatus {
PENDING,
SUCCESS,
FAILURE
}
}

View File

@ -87,7 +87,7 @@ public class HomeActivity extends AppCompatActivity {
syncFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(HomeActivity.this, SyncActivity.class));
startActivity(new Intent(HomeActivity.this, ExchangeActivity.class));
}
});
}
@ -113,6 +113,7 @@ public class HomeActivity extends AppCompatActivity {
}
}
private OnRecyclerItemClickListener<Integer> onRecyclerItemClickListener() {
return new OnRecyclerItemClickListener<Integer>() {
@Override

View File

@ -30,7 +30,6 @@ import lu.circl.mispbump.auxiliary.PreferenceManager;
import lu.circl.mispbump.auxiliary.QrCodeGenerator;
import lu.circl.mispbump.auxiliary.RandomString;
import lu.circl.mispbump.fragments.CameraFragment;
import lu.circl.mispbump.fragments.UploadSettingsFragment;
import lu.circl.mispbump.models.SyncInformation;
import lu.circl.mispbump.models.UploadInformation;
import lu.circl.mispbump.security.DiffieHellman;
@ -101,6 +100,7 @@ public class SyncActivity extends AppCompatActivity {
diffieHellman = DiffieHellman.getInstance();
qrCodeGenerator = new QrCodeGenerator(SyncActivity.this);
publicKeyQrCode = qrCodeGenerator.generateQrCode(DiffieHellman.publicKeyToString(diffieHellman.getPublicKey()));
uploadInformation = new UploadInformation();
@ -111,7 +111,7 @@ public class SyncActivity extends AppCompatActivity {
qrFrame = findViewById(R.id.qrFrame);
qrCode = findViewById(R.id.qrCode);
qrHint = findViewById(R.id.qrHint);
qrHint = findViewById(R.id.qrInfo);
prevButton = findViewById(R.id.prevButton);
prevButton.setOnClickListener(onPrevClicked);
@ -153,7 +153,6 @@ public class SyncActivity extends AppCompatActivity {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String camTag = CameraFragment.class.getSimpleName();
String settingsTag = UploadSettingsFragment.class.getSimpleName();
switch (state) {
case PUBLIC_KEY:
@ -167,11 +166,6 @@ public class SyncActivity extends AppCompatActivity {
fragmentTransaction.add(R.id.fragmentContainer, cameraFragment, camTag);
}
UploadSettingsFragment uploadSettingsFragment = (UploadSettingsFragment) fragmentManager.findFragmentByTag(settingsTag);
if (uploadSettingsFragment != null) {
fragmentTransaction.hide(uploadSettingsFragment);
}
fragmentTransaction.commit();
break;
}
@ -206,7 +200,7 @@ public class SyncActivity extends AppCompatActivity {
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
prevButton.setVisibility(View.VISIBLE);
nextButton.setVisibility(View.VISIBLE);
cameraFragment.disablePreview();
// cameraFragment.disablePreview();
qrReceivedFeedback(true);
break;
case SYNC_INFO_SHOW:
@ -214,7 +208,7 @@ public class SyncActivity extends AppCompatActivity {
nextButton.setImageDrawable(getDrawable(R.drawable.ic_arrow_forward));
nextButton.setVisibility(View.INVISIBLE);
prevButton.setVisibility(View.VISIBLE);
cameraFragment.enablePreview();
// cameraFragment.enablePreview();
qrReceivedFeedback(false);
break;
case SYNC_INFO_SHOW_AND_RECEIVED:
@ -222,7 +216,7 @@ public class SyncActivity extends AppCompatActivity {
nextButton.setImageDrawable(getDrawable(R.drawable.ic_check));
nextButton.setVisibility(View.VISIBLE);
prevButton.setVisibility(View.VISIBLE);
cameraFragment.disablePreview();
// cameraFragment.disablePreview();
qrReceivedFeedback(true);
break;
}
@ -294,17 +288,17 @@ public class SyncActivity extends AppCompatActivity {
if (uploadInformationList != null) {
for (final UploadInformation ui : uploadInformationList) {
if (ui.getRemote().organisation.uuid.equals(remoteSyncInfo.organisation.uuid)) {
DialogManager.syncAlreadyExistsDialog(SyncActivity.this, new DialogManager.IDialogFeedback() {
@Override
public void positive() {
uploadInformation.setUuid(ui.getUuid());
}
@Override
public void negative() {
finish();
}
});
// DialogManager.syncAlreadyExistsDialog(SyncActivity.this, new DialogManager.IDialogFeedback() {
// @Override
// public void positive() {
// uploadInformation.setUuid(ui.getUuid());
// }
//
// @Override
// public void negative() {
// finish();
// }
// });
}
}
}

View File

@ -20,13 +20,21 @@ import lu.circl.mispbump.security.DiffieHellman;
public class DialogManager {
public static void syncAlreadyExistsDialog(Context context, final IDialogFeedback callback) {
public static void syncAlreadyExistsDialog(SyncInformation oldSync, SyncInformation newSync, Context context, final IDialogFeedback callback) {
final AlertDialog.Builder adb = new AlertDialog.Builder(context);
adb.setTitle("Sync information already exists");
adb.setMessage("You already synced with this organisation, would you like to update the information?" +
"\nUpdating the information will reset the current authkey!");
adb.setPositiveButton("Update", new DialogInterface.OnClickListener() {
// this dialog needs definite user feedback
adb.setCancelable(false);
if (oldSync.organisation.name.equals(newSync.organisation.name)) {
adb.setTitle("Already Synced with " + oldSync.organisation.name);
} else {
adb.setTitle("Already Synced with " + oldSync.organisation.name + "(Now:" + newSync.organisation.name + ")");
}
adb.setMessage("");
adb.setPositiveButton("Override Credentials", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null) {
@ -35,7 +43,7 @@ public class DialogManager {
}
});
adb.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
adb.setNegativeButton("Just Update Content", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (callback != null) {
@ -298,4 +306,6 @@ public class DialogManager {
void positive();
void negative();
}
}

View File

@ -407,6 +407,7 @@ public class PreferenceManager {
for (UploadInformation ui : cachedUploadInformationList) {
if (ui.getUuid().compareTo(uuid) == 0) {
// if is last element, then clear everything including IV and key in KeyStore
if (cachedUploadInformationList.size() == 1) {
clearUploadInformation();
} else {

View File

@ -22,10 +22,14 @@ public class QrCodeGenerator {
}
public Bitmap generateQrCode(String content) {
int size = getDisplaySize().x;
if (size > getDisplaySize().y) {
size = getDisplaySize().y;
Point displaySize = new Point();
callingActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
int size = displaySize.x;
if (size > displaySize.y) {
size = displaySize.y;
}
size = (int)(size * 0.8);
@ -45,13 +49,6 @@ public class QrCodeGenerator {
return null;
}
public Point getDisplaySize() {
Point displaySize = new Point();
callingActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
return displaySize;
}
private Bitmap createBitmap(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();

View File

@ -1,8 +1,6 @@
package lu.circl.mispbump.fragments;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@ -33,7 +31,6 @@ import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
import android.util.Log;
import android.util.Size;
import android.util.SparseArray;
import android.util.SparseIntArray;
@ -121,8 +118,6 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
}
}
private static final String TAG = "CAMERA";
private View hideCamView;
private QrScanCallback qrResultCallback;
@ -374,19 +369,30 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
@Override
public void onResume() {
super.onResume();
enablePreview();
hideCamView.setVisibility(View.GONE);
startBackgroundThread();
imageProcessingThread = new ImageProcessingThread();
imageProcessingThread.start();
if (autoFitTextureView.isAvailable()) {
openCamera(autoFitTextureView.getWidth(), autoFitTextureView.getHeight());
} else {
autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
@Override
public void onPause() {
super.onPause();
closeCamera();
stopBackgroundThread();
if (imageProcessingThread.isAlive()) {
imageProcessingThread.isRunning = false;
}
super.onPause();
}
private void requestCameraPermission() {
@ -463,7 +469,7 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
}
break;
default:
Log.e(TAG, "Display rotation is invalid: " + displayRotation);
return;
}
Point displaySize = new Point();
@ -778,6 +784,7 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
public interface QrScanCallback {
void qrScanResult(String qrData);
}
private boolean readQrEnabled = true;
private BarcodeDetector barcodeDetector;
private RenderScript renderScript;
@ -834,62 +841,62 @@ public class CameraFragment extends Fragment implements ActivityCompat.OnRequest
readQrEnabled = enabled;
}
public void disablePreview() {
if (hideCamView.getAlpha() == 1 && hideCamView.getVisibility() == View.VISIBLE) {
closeCamera();
stopBackgroundThread();
if (imageProcessingThread.isAlive()) {
imageProcessingThread.isRunning = false;
}
return;
}
hideCamView.setAlpha(0f);
hideCamView.setVisibility(View.VISIBLE);
hideCamView.animate()
.alpha(1f)
.setDuration(250)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
closeCamera();
stopBackgroundThread();
if (imageProcessingThread.isAlive()) {
imageProcessingThread.isRunning = false;
}
}
});
}
public void enablePreview() {
startBackgroundThread();
imageProcessingThread = new ImageProcessingThread();
imageProcessingThread.start();
if (autoFitTextureView.isAvailable()) {
openCamera(autoFitTextureView.getWidth(), autoFitTextureView.getHeight());
} else {
autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
hideCamView.setVisibility(View.VISIBLE);
hideCamView.setAlpha(1f);
hideCamView.animate()
.alpha(0f)
.setDuration(1000)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
hideCamView.setVisibility(View.GONE);
}
});
}
// public void disablePreview() {
//
// if (hideCamView.getAlpha() == 1 && hideCamView.getVisibility() == View.VISIBLE) {
// closeCamera();
// stopBackgroundThread();
//
// if (imageProcessingThread.isAlive()) {
// imageProcessingThread.isRunning = false;
// }
//
// return;
// }
//
// hideCamView.setAlpha(0f);
// hideCamView.setVisibility(View.VISIBLE);
// hideCamView.animate()
// .alpha(1f)
// .setDuration(250)
// .setListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// closeCamera();
// stopBackgroundThread();
//
// if (imageProcessingThread.isAlive()) {
// imageProcessingThread.isRunning = false;
// }
// }
// });
// }
//
// public void enablePreview() {
//
// startBackgroundThread();
//
// imageProcessingThread = new ImageProcessingThread();
// imageProcessingThread.start();
//
// if (autoFitTextureView.isAvailable()) {
// openCamera(autoFitTextureView.getWidth(), autoFitTextureView.getHeight());
// } else {
// autoFitTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
// }
//
// hideCamView.setVisibility(View.VISIBLE);
// hideCamView.setAlpha(1f);
// hideCamView.animate()
// .alpha(0f)
// .setDuration(1000)
// .setListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
// hideCamView.setVisibility(View.GONE);
// }
// });
// }
private void setUpBarcodeDetector() {
barcodeDetector = new BarcodeDetector.Builder(getActivity())

View File

@ -60,11 +60,11 @@ public class SyncFragmentAdapter extends FragmentPagerAdapter {
public void disableCameraPreview() {
if (cameraFragment_1 != null) {
cameraFragment_1.disablePreview();
// cameraFragment_1.disablePreview();
}
if (cameraFragment_2 != null) {
cameraFragment_2.disablePreview();
// cameraFragment_2.disablePreview();
}
}

View File

@ -3,13 +3,11 @@ package lu.circl.mispbump.security;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Base64;
import android.util.Log;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
@ -29,8 +27,6 @@ import javax.crypto.spec.GCMParameterSpec;
public class KeyStoreWrapper {
private static final String TAG = "KeyStoreWrapper";
public static final String USER_INFO_ALIAS = "ALIAS_USER_INFO";
public static final String USER_ORGANISATION_INFO_ALIAS = "ALIAS_USER_ORGANISATION_INFO";
public static final String AUTOMATION_ALIAS = "ALIAS_AUTOMATION_KEY";
@ -44,6 +40,7 @@ public class KeyStoreWrapper {
/**
* Wraps the android key store to easily encrypt and decrypt sensitive data.
*
* @param alias identifies a key store entry (see public static ALIAS variables).
*/
public KeyStoreWrapper(String alias) {
@ -75,7 +72,6 @@ public class KeyStoreWrapper {
}
/**
*
* @return SecretKey associated with the given alias.
*/
private SecretKey getStoredKey() {
@ -102,6 +98,7 @@ public class KeyStoreWrapper {
/**
* Generates a new key.
*
* @return the newly generated key.
*/
private SecretKey generateKey() {
@ -154,12 +151,13 @@ public class KeyStoreWrapper {
/**
* Encrypt data with given algorithm and key associated with alias.
*
* @param data data to encrypt.
* @return encrypted data as String.
* @throws NoSuchPaddingException padding not found
* @throws NoSuchAlgorithmException algorithm not found
* @throws InvalidKeyException invalid key
* @throws BadPaddingException bad padding
* @throws NoSuchPaddingException padding not found
* @throws NoSuchAlgorithmException algorithm not found
* @throws InvalidKeyException invalid key
* @throws BadPaddingException bad padding
* @throws IllegalBlockSizeException illegal block size
*/
public String encrypt(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
@ -181,22 +179,17 @@ public class KeyStoreWrapper {
/**
* Decrypts data with given algorithm and key associated with alias.
*
* @param input encrypted data.
* @return decrypted data as String.
* @throws NoSuchPaddingException padding not found
* @throws NoSuchAlgorithmException algorithm not found
* @throws NoSuchPaddingException padding not found
* @throws NoSuchAlgorithmException algorithm not found
* @throws InvalidAlgorithmParameterException invalid algorithm parameters
* @throws InvalidKeyException invalid key
* @throws BadPaddingException bad padding
* @throws IllegalBlockSizeException illegal block size
* @throws InvalidKeyException invalid key
* @throws BadPaddingException bad padding
* @throws IllegalBlockSizeException illegal block size
*/
public String decrypt(String input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// extract iv from save data
// String[] parts = input.split(":::");
// byte[] iv = Base64.decode(parts[0], Base64.DEFAULT);
// byte[] data = Base64.decode(parts[1], Base64.DEFAULT);
byte[] in = Base64.decode(input, Base64.NO_WRAP);
IvAndData ivAndData = splitCombinedArray(in, 12);
@ -217,9 +210,6 @@ public class KeyStoreWrapper {
KeyStore ks = KeyStore.getInstance(KEYSTORE_PROVIDER);
ks.load(null);
Log.i(TAG, "Size: " + ks.size());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
@ -240,14 +230,12 @@ public class KeyStoreWrapper {
/**
* Combine IV and encrypted data.
* @param iv initialisation vector
*
* @param iv initialisation vector
* @param encryptedData encrypted data
* @return combination of iv and encrypted data
*/
private byte[] getCombinedArray(byte[] iv, byte[] encryptedData) {
Log.i(TAG, "iv length = " + iv.length);
byte[] combined = new byte[iv.length + encryptedData.length];
for (int i = 0; i < combined.length; ++i) {
combined[i] = i < iv.length ? iv[i] : encryptedData[i - iv.length];

View File

@ -35,7 +35,7 @@
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/qrHint"
android:id="@+id/qrInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_info_outline"
@ -47,7 +47,7 @@
android:textColor="@color/colorPrimaryDark"/>
<TextView
android:id="@+id/qrHint2"
android:id="@+id/qrInfoStatic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_info_outline"
@ -98,62 +98,4 @@
</LinearLayout>
<!--<LinearLayout-->
<!--app:layout_behavior=".customViews.ExtendedBottomSheetBehavior"-->
<!--android:id="@+id/bottomSheet"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:orientation="vertical"-->
<!--android:background="@drawable/rect_rounded_top"-->
<!--android:backgroundTint="@color/colorPrimary"-->
<!--app:behavior_peekHeight="64dp">-->
<!--<LinearLayout-->
<!--android:orientation="horizontal"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content">-->
<!--<ImageButton-->
<!--android:id="@+id/prevButton"-->
<!--android:layout_width="64dp"-->
<!--android:layout_height="64dp"-->
<!--android:background="?attr/selectableItemBackground"-->
<!--android:padding="8dp"-->
<!--app:layout_constraintStart_toStartOf="parent"-->
<!--app:layout_constraintTop_toTopOf="parent"-->
<!--app:srcCompat="@drawable/ic_arrow_back" />-->
<!--<ImageView-->
<!--android:visibility="invisible"-->
<!--android:id="@+id/bottomSheetIcon"-->
<!--android:layout_weight="1"-->
<!--android:layout_width="0dp"-->
<!--android:layout_height="32dp"-->
<!--android:layout_gravity="center_vertical"-->
<!--android:src="@drawable/ic_check_outline" />-->
<!--<ImageButton-->
<!--android:id="@+id/nextButton"-->
<!--android:layout_width="64dp"-->
<!--android:layout_height="64dp"-->
<!--android:background="?attr/selectableItemBackground"-->
<!--android:padding="8dp"-->
<!--app:layout_constraintEnd_toEndOf="parent"-->
<!--app:layout_constraintTop_toTopOf="parent"-->
<!--app:srcCompat="@drawable/ic_arrow_forward" />-->
<!--</LinearLayout>-->
<!--<TextView-->
<!--android:id="@+id/bottomSheetText"-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:paddingStart="16dp"-->
<!--android:paddingEnd="16dp"-->
<!--android:paddingBottom="16dp"-->
<!--android:gravity="top"-->
<!--android:layout_gravity="center"-->
<!--android:text="Received public key from partner"-->
<!--android:textColor="@color/white" />-->
<!--</LinearLayout>-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>