diff --git a/.idea/misc.xml b/.idea/misc.xml index da7759f..93a9df2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -38,7 +38,7 @@ - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1f3a32c..b2652aa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,11 +1,10 @@ - - - + + - + + - + - + - - + android:label="@string/login" /> - + android:label="@string/app_name" /> - + android:theme="@style/AppTheme.Translucent" /> - + android:parentActivityName=".activities.HomeActivity" /> + android:parentActivityName=".activities.HomeActivity" /> + android:parentActivityName=".activities.HomeActivity" /> + android:theme="@style/AppTheme.Translucent" /> \ No newline at end of file diff --git a/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java b/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java new file mode 100644 index 0000000..218328f --- /dev/null +++ b/app/src/main/java/lu/circl/mispbump/activities/ExchangeActivity.java @@ -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 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 + } +} diff --git a/app/src/main/java/lu/circl/mispbump/activities/HomeActivity.java b/app/src/main/java/lu/circl/mispbump/activities/HomeActivity.java index 7b97cd6..51f4095 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/HomeActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/HomeActivity.java @@ -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 onRecyclerItemClickListener() { return new OnRecyclerItemClickListener() { @Override diff --git a/app/src/main/java/lu/circl/mispbump/activities/SyncActivity.java b/app/src/main/java/lu/circl/mispbump/activities/SyncActivity.java index 472df9f..373596b 100644 --- a/app/src/main/java/lu/circl/mispbump/activities/SyncActivity.java +++ b/app/src/main/java/lu/circl/mispbump/activities/SyncActivity.java @@ -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(); +// } +// }); } } } diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/DialogManager.java b/app/src/main/java/lu/circl/mispbump/auxiliary/DialogManager.java index b09f3bf..12dfeb2 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/DialogManager.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/DialogManager.java @@ -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(); } + + } diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java index 70b4677..5590077 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/PreferenceManager.java @@ -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 { diff --git a/app/src/main/java/lu/circl/mispbump/auxiliary/QrCodeGenerator.java b/app/src/main/java/lu/circl/mispbump/auxiliary/QrCodeGenerator.java index 3f0b100..0ff165e 100644 --- a/app/src/main/java/lu/circl/mispbump/auxiliary/QrCodeGenerator.java +++ b/app/src/main/java/lu/circl/mispbump/auxiliary/QrCodeGenerator.java @@ -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(); diff --git a/app/src/main/java/lu/circl/mispbump/fragments/CameraFragment.java b/app/src/main/java/lu/circl/mispbump/fragments/CameraFragment.java index f293c4c..8c87276 100644 --- a/app/src/main/java/lu/circl/mispbump/fragments/CameraFragment.java +++ b/app/src/main/java/lu/circl/mispbump/fragments/CameraFragment.java @@ -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()) diff --git a/app/src/main/java/lu/circl/mispbump/fragments/SyncFragmentAdapter.java b/app/src/main/java/lu/circl/mispbump/fragments/SyncFragmentAdapter.java index bb59154..51a1c1e 100644 --- a/app/src/main/java/lu/circl/mispbump/fragments/SyncFragmentAdapter.java +++ b/app/src/main/java/lu/circl/mispbump/fragments/SyncFragmentAdapter.java @@ -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(); } } diff --git a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java index 0576074..4d2677a 100644 --- a/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java +++ b/app/src/main/java/lu/circl/mispbump/security/KeyStoreWrapper.java @@ -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 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]; diff --git a/app/src/main/res/layout/activity_sync.xml b/app/src/main/res/layout/activity_sync.xml index 137ecff..5535105 100644 --- a/app/src/main/res/layout/activity_sync.xml +++ b/app/src/main/res/layout/activity_sync.xml @@ -35,7 +35,7 @@ android:layout_height="wrap_content"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file