remove pgp handler

This commit is contained in:
Mohamed Zenadi 2017-08-05 18:46:26 +01:00 committed by Mohamed Zenadi
parent a69b6392aa
commit 55db404f14
2 changed files with 0 additions and 844 deletions

View file

@ -34,14 +34,6 @@
android:value="com.zeapo.pwdstore.PasswordStore" />
</activity>
<activity android:name=".crypto.PgpHandler"
android:parentActivityName=".PasswordStore"
android:configChanges="orientation|screenSize">
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="com.zeapo.pwdstore.PasswordStore" />
</activity>
<activity android:name=".SshKeyGen"
android:parentActivityName=".PasswordStore">

View file

@ -1,836 +0,0 @@
package com.zeapo.pwdstore.crypto;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.zeapo.pwdstore.BuildConfig;
import com.zeapo.pwdstore.PasswordEntry;
import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.SelectFolderFragment;
import com.zeapo.pwdstore.UserPreference;
import com.zeapo.pwdstore.pwgenDialogFragment;
import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils;
import org.openintents.openpgp.IOpenPgpService2;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpServiceConnection;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;
public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConnection.OnBound {
private static DelayShow delayTask;
private OpenPgpServiceConnection mServiceConnection;
private Set<String> keyIDs = new HashSet<>();
SharedPreferences settings;
private Activity activity;
ClipboardManager clipboard;
SelectFolderFragment passwordList;
private Intent selectFolderData;
private boolean registered;
public static final int REQUEST_CODE_SIGN = 9910;
public static final int REQUEST_CODE_ENCRYPT = 9911;
public static final int REQUEST_CODE_SIGN_AND_ENCRYPT = 9912;
public static final int REQUEST_CODE_DECRYPT_AND_VERIFY = 9913;
public static final int REQUEST_CODE_GET_KEY = 9914;
public static final int REQUEST_CODE_GET_KEY_IDS = 9915;
public static final int REQUEST_CODE_EDIT = 9916;
public static final int REQUEST_CODE_SELECT_FOLDER = 9917;
private PasswordEntry passwordEntry = null;
public final class Constants {
public static final String TAG = "Keychain";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
this.activity = this;
this.clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
if (getIntent().getStringExtra("Operation").equals("ENCRYPT")) {
setTitle("New password");
}
// some persistance
settings = PreferenceManager.getDefaultSharedPreferences(this);
String providerPackageName = settings.getString("openpgp_provider_list", "");
keyIDs = settings.getStringSet("openpgp_key_ids_set", new HashSet<String>());
registered = false;
if (TextUtils.isEmpty(providerPackageName)) {
Toast.makeText(this, this.getResources().getString(R.string.provider_toast_text), Toast.LENGTH_LONG).show();
Intent intent = new Intent(this, UserPreference.class);
startActivity(intent);
// a small hack to avoid eternal loop later, have to be solved via a startactivityforresult()
setResult(RESULT_CANCELED);
finish();
} else {
// bind to service
mServiceConnection = new OpenPgpServiceConnection(
PgpHandler.this, providerPackageName, this);
mServiceConnection.bindToService();
registered = true;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
@Override
public void onStop() {
super.onStop();
if (this.registered && this.mServiceConnection.isBound())
try {
this.mServiceConnection.unbindFromService();
} catch (Exception e) {
// ignore any errors, we'll stop anyway.
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
switch (getIntent().getStringExtra("Operation")) {
case "ENCRYPT":
getMenuInflater().inflate(R.menu.pgp_handler_new_password, menu);
break;
case "SELECTFOLDER":
getMenuInflater().inflate(R.menu.pgp_handler_select_folder, menu);
break;
default:
getMenuInflater().inflate(R.menu.pgp_handler, menu);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case android.R.id.home:
setResult(RESULT_CANCELED);
finish();
return true;
case R.id.copy_password:
copyPasswordToClipBoard();
break;
case R.id.share_password_as_plaintext:
shareAsPlaintext();
break;
case R.id.edit_password:
editPassword();
break;
case R.id.crypto_confirm_add:
encrypt(new Intent());
break;
case R.id.crypto_cancel_add:
setResult(RESULT_CANCELED);
finish();
return true;
case R.id.crypto_select:
selectFolder();
break;
}
return super.onOptionsItemSelected(item);
}
private void selectFolder() {
if (selectFolderData == null || passwordList == null) {
Log.wtf(Constants.TAG, "Folder selected while the app didn't ask for one to be selected?");
}
selectFolderData.putExtra("SELECTED_FOLDER_PATH", passwordList.getCurrentDir().getAbsolutePath());
setResult(RESULT_OK, selectFolderData);
finish();
}
public void editPassword() {
// if in encrypt or in decrypt and password is invisible
// (because !showPassword, so this will instantly close), do nothing
if (findViewById(R.id.crypto_password_show) == null
|| findViewById(R.id.crypto_container).getVisibility() != View.VISIBLE)
return;
CharSequence category = ((TextView) findViewById(R.id.crypto_password_category_decrypt)).getText();
CharSequence file = ((TextView) findViewById(R.id.crypto_password_file)).getText();
CharSequence password = ((TextView) findViewById(R.id.crypto_password_show)).getText();
CharSequence extra = ((TextView) findViewById(R.id.crypto_extra_show)).getText();
setContentView(R.layout.encrypt_layout);
Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf");
((EditText) findViewById(R.id.crypto_password_edit)).setTypeface(monoTypeface);
((EditText) findViewById(R.id.crypto_extra_edit)).setTypeface(monoTypeface);
((TextView) findViewById(R.id.crypto_password_category_decrypt)).setText(category);
((EditText) findViewById(R.id.crypto_password_file_edit)).setText(file);
((EditText) findViewById(R.id.crypto_password_edit)).setText(password);
((EditText) findViewById(R.id.crypto_extra_edit)).setText(extra);
// strictly editing only i.e. can't save this password's info to another file by changing name
findViewById(R.id.crypto_password_file_edit).setEnabled(false);
// the original intent was to decrypt so FILE_PATH will have the file, not enclosing dir
// PgpCallback expects the dir when encrypting
String filePath = getIntent().getExtras().getString("FILE_PATH");
String directoryPath = filePath.substring(0, filePath.lastIndexOf(File.separator));
Intent intent = new Intent(this, PgpHandler.class);
intent.putExtra("FILE_PATH", directoryPath);
intent.putExtra("Operation", "ENCRYPT");
intent.putExtra("fromDecrypt", true);
setIntent(intent);
// recreate the options menu to be the encrypt one
invalidateOptionsMenu();
}
public void shareAsPlaintext() {
if (findViewById(R.id.share_password_as_plaintext) == null)
return;
final String decodedPassword = passwordEntry != null ? passwordEntry.getPassword() : "";
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, decodedPassword);
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_plaintext_password_to)));//Always show a picker to give the user a chance to cancel
}
public void copyPasswordToClipBoard() {
if (findViewById(R.id.crypto_password_show) == null)
return;
setTimer();
final String decodedPassword = passwordEntry != null ? passwordEntry.getPassword() : "";
ClipData clip = ClipData.newPlainText("pgp_handler_result_pm", decodedPassword);
clipboard.setPrimaryClip(clip);
int clearAfter = 45;
try {
clearAfter = Integer.parseInt(settings.getString("general_show_time", "45"));
} catch (NumberFormatException e) {
// ignore and keep default
}
showToast(this.getResources().getString(R.string.clipboard_password_toast_text, clearAfter));
}
public void copyUsernameToClipBoard(final String username) {
ClipData clip = ClipData.newPlainText("pgp_handler_result_pm", username);
clipboard.setPrimaryClip(clip);
showToast(this.getResources().getString(R.string.clipboard_username_toast_text));
}
public void handleClick(View view) {
switch (view.getId()) {
case R.id.generate_password:
DialogFragment df = new pwgenDialogFragment();
df.show(getFragmentManager(), "generator");
default:
Log.wtf(Constants.TAG, "This should not happen.... PgpHandler.java#handleClick(View) default reached.");
// should not happen
}
}
private void handleError(final OpenPgpError error) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(PgpHandler.this,
"Error from OpenKeyChain : " + error.getMessage(),
Toast.LENGTH_LONG).show();
Log.e(Constants.TAG, "onError getErrorId:" + error.getErrorId());
Log.e(Constants.TAG, "onError getMessage:" + error.getMessage());
}
});
}
private void showToast(final String message) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(PgpHandler.this,
message,
Toast.LENGTH_SHORT).show();
}
});
}
public class DelayShow extends AsyncTask<Void, Integer, Boolean> {
ProgressBar pb;
boolean clearClipboard = true;
int current, showTime;
@Override
protected void onPreExecute() {
try {
showTime = Integer.parseInt(settings.getString("general_show_time", "45"));
} catch (NumberFormatException e) {
showTime = 45;
}
current = 0;
LinearLayout container = (LinearLayout) findViewById(R.id.crypto_container);
container.setVisibility(View.VISIBLE);
TextView extraText = (TextView) findViewById(R.id.crypto_extra_show);
if (extraText.getText().length() != 0)
findViewById(R.id.crypto_extra_show_layout).setVisibility(View.VISIBLE);
if (showTime == 0) {
// treat 0 as forever, and the user must exit and/or clear clipboard on their own
cancel(true);
} else {
this.pb = (ProgressBar) findViewById(R.id.pbLoading);
this.pb.setMax(showTime);
}
}
@Override
protected Boolean doInBackground(Void... params) {
while (current < showTime) {
SystemClock.sleep(1000);
current++;
publishProgress(current);
}
return true;
}
@Override
protected void onPostExecute(Boolean b) {
// only clear the clipboard if we automatically copied the password to it
if (settings.getBoolean("copy_on_decrypt", true) && clearClipboard) {
Log.d("DELAY_SHOW", "Clearing the clipboard");
ClipData clip = ClipData.newPlainText("pgp_handler_result_pm", "");
clipboard.setPrimaryClip(clip);
if (settings.getBoolean("clear_clipboard_20x", false)) {
Handler handler = new Handler();
for (int i = 0; i < 19; i++) {
final String count = String.valueOf(i);
handler.postDelayed(new Runnable() {
@Override
public void run() {
clipboard.setPrimaryClip(ClipData.newPlainText(count, count));
}
}, i * 500);
}
}
}
passwordEntry = null;
if (findViewById(R.id.crypto_password_show) != null) {
// clear password; if decrypt changed to encrypt layout via edit button, no need
((TextView) findViewById(R.id.crypto_password_show)).setText("");
((TextView) findViewById(R.id.crypto_extra_show)).setText("");
findViewById(R.id.crypto_extra_show_layout).setVisibility(View.INVISIBLE);
findViewById(R.id.crypto_container).setVisibility(View.INVISIBLE);
activity.setResult(RESULT_CANCELED);
activity.finish();
}
}
@Override
protected void onProgressUpdate(Integer... values) {
this.pb.setProgress(values[0]);
}
public void setClearClipboard(boolean value) {
clearClipboard = value;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(Constants.TAG, "onActivityResult resultCode: " + resultCode);
if (data == null) {
setResult(RESULT_CANCELED, null);
finish();
return;
}
// try again after user interaction
if (resultCode == RESULT_OK) {
/*
* The data originally given to one of the methods above, is again
* returned here to be used when calling the method again after user
* interaction. The Intent now also contains results from the user
* interaction, for example selected key ids.
*/
switch (requestCode) {
case REQUEST_CODE_ENCRYPT: {
encrypt(data);
break;
}
case REQUEST_CODE_DECRYPT_AND_VERIFY: {
decryptAndVerify(data);
break;
}
case REQUEST_CODE_GET_KEY_IDS:
getKeyIds(data);
break;
case REQUEST_CODE_EDIT: {
edit(data);
break;
}
default:
setResult(RESULT_OK);
finish();
}
} else if (resultCode == RESULT_CANCELED) {
setResult(RESULT_CANCELED, data);
finish();
}
}
private void selectFolder(Intent data) {
if (data.getStringExtra("Operation") == null || !data.getStringExtra("Operation").equals("SELECTFOLDER")) {
Log.e(Constants.TAG, "PgpHandler#selectFolder(Intent) triggered with incorrect intent.");
if (BuildConfig.DEBUG) {
throw new UnsupportedOperationException("Triggered with incorrect intent.");
}
return;
}
Log.d(Constants.TAG, "PgpHandler#selectFolder(Intent).");
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
passwordList = new SelectFolderFragment();
Bundle args = new Bundle();
args.putString("Path", PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath());
passwordList.setArguments(args);
getSupportActionBar().show();
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentTransaction.replace(R.id.pgp_handler_linearlayout, passwordList, "PasswordsList");
fragmentTransaction.commit();
this.selectFolderData = data;
}
public class PgpCallback implements OpenPgpApi.IOpenPgpCallback {
boolean returnToCiphertextField;
ByteArrayOutputStream os;
int requestCode;
private PgpCallback(boolean returnToCiphertextField, ByteArrayOutputStream os, int requestCode) {
this.returnToCiphertextField = returnToCiphertextField;
this.os = os;
this.requestCode = requestCode;
}
@Override
public void onReturn(Intent result) {
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS: {
// encrypt/decrypt/sign/verify
final TextView textViewPassword = (TextView) findViewById(R.id.crypto_password_show);
if (requestCode == REQUEST_CODE_DECRYPT_AND_VERIFY && os != null) {
try {
if (returnToCiphertextField) {
final boolean showPassword = settings.getBoolean("show_password", true);
final boolean showExtraContent = settings.getBoolean("show_extra_content", true);
findViewById(R.id.crypto_container).setVisibility(View.VISIBLE);
Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf");
final PasswordEntry entry = new PasswordEntry(os);
passwordEntry = entry;
textViewPassword.setTypeface(monoTypeface);
textViewPassword.setText(entry.getPassword());
Button toggleVisibilityButton = (Button) findViewById(R.id.crypto_password_toggle_show);
toggleVisibilityButton.setVisibility(showPassword ? View.GONE : View.VISIBLE);
textViewPassword.setTransformationMethod(showPassword ? null : new HoldToShowPasswordTransformation(toggleVisibilityButton, new Runnable() {
@Override
public void run() {
textViewPassword.setText(entry.getPassword());
}
}));
if (entry.hasExtraContent()) {
findViewById(R.id.crypto_extra_show_layout).setVisibility(showExtraContent ? View.VISIBLE : View.GONE);
final TextView extraView = (TextView) findViewById(R.id.crypto_extra_show);
extraView.setTypeface(monoTypeface);
extraView.setText(entry.getExtraContent());
if (entry.hasUsername()) {
findViewById(R.id.crypto_username_show).setVisibility(View.VISIBLE);
findViewById(R.id.crypto_username_show_label).setVisibility(View.VISIBLE);
findViewById(R.id.crypto_copy_username).setVisibility(View.VISIBLE);
findViewById(R.id.crypto_copy_username).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyUsernameToClipBoard(entry.getUsername());
}
});
final TextView usernameView = (TextView) findViewById(R.id.crypto_username_show);
usernameView.setTypeface(monoTypeface);
usernameView.setText(entry.getUsername());
} else {
findViewById(R.id.crypto_username_show).setVisibility(View.GONE);
findViewById(R.id.crypto_username_show_label).setVisibility(View.GONE);
findViewById(R.id.crypto_copy_username).setVisibility(View.GONE);
}
}
if (settings.getBoolean("copy_on_decrypt", true)) {
copyPasswordToClipBoard();
}
} else {
Log.d("PGPHANDLER", "Error message after decrypt : " + os.toString());
}
} catch (UnsupportedEncodingException e) {
Log.e(Constants.TAG, "UnsupportedEncodingException", e);
}
}
// encrypt
if (requestCode == REQUEST_CODE_ENCRYPT && os != null) {
try {
String path = getIntent().getExtras().getString("FILE_PATH")
+ "/" + ((EditText) findViewById(R.id.crypto_password_file_edit)).getText().toString()
+ ".gpg";
OutputStream outputStream = FileUtils.openOutputStream(new File(path));
outputStream.write(os.toByteArray());
outputStream.close();
Intent data = new Intent();
data.putExtra("CREATED_FILE", path);
data.putExtra("NAME", ((EditText) findViewById(R.id.crypto_password_file_edit)).getText().toString());
// if coming from decrypt screen->edit button
if (getIntent().getBooleanExtra("fromDecrypt", false)) {
data.putExtra("needCommit", true);
}
setResult(RESULT_OK, data);
finish();
} catch (Exception e) {
Log.e(Constants.TAG, "UnsupportedEncodingException", e);
}
}
// get key ids
if (result.hasExtra(OpenPgpApi.RESULT_KEY_IDS)) {
long[] ids = result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS);
Set<String> keys = new HashSet<>();
for (long id : ids) keys.add(String.valueOf(id)); // use Long
settings.edit().putStringSet("openpgp_key_ids_set", keys).apply();
showToast("PGP key selected");
setResult(RESULT_OK);
finish();
}
// edit
if (requestCode == REQUEST_CODE_EDIT && os != null) {
try {
if (returnToCiphertextField) {
findViewById(R.id.crypto_container).setVisibility(View.VISIBLE);
Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf");
final PasswordEntry entry = new PasswordEntry(os);
passwordEntry = entry;
textViewPassword
.setTypeface(monoTypeface);
textViewPassword
.setText(entry.getPassword());
String extraContent = os.toString("UTF-8").replaceFirst(".*\n", "");
if (extraContent.length() != 0) {
((TextView) findViewById(R.id.crypto_extra_show))
.setTypeface(monoTypeface);
((TextView) findViewById(R.id.crypto_extra_show))
.setText(extraContent);
}
editPassword();
} else {
Log.d("PGPHANDLER", "Error message after decrypt : " + os.toString());
}
} catch (UnsupportedEncodingException e) {
Log.e(Constants.TAG, "UnsupportedEncodingException", e);
}
}
break;
}
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: {
Log.i("PgpHandler", "RESULT_CODE_USER_INTERACTION_REQUIRED");
PendingIntent pi = result.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
try {
PgpHandler.this.startIntentSenderForResult(pi.getIntentSender(),
requestCode, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(Constants.TAG, "SendIntentException", e);
}
break;
}
case OpenPgpApi.RESULT_CODE_ERROR: {
// TODO show what kind of error it is
/* For example:
* No suitable key found -> no key in OpenKeyChain
*
* Check in open-pgp-lib how their definitions and error code
*/
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
handleError(error);
break;
}
}
}
}
public void getKeyIds(Intent data) {
data.setAction(OpenPgpApi.ACTION_GET_KEY_IDS);
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
api.executeApiAsync(data, null, null, new PgpCallback(false, null, PgpHandler.REQUEST_CODE_GET_KEY_IDS));
}
public void decryptAndVerify(Intent data) {
data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
try {
InputStream is = FileUtils.openInputStream(new File(getIntent().getExtras().getString("FILE_PATH")));
ByteArrayOutputStream os = new ByteArrayOutputStream();
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
api.executeApiAsync(data, is, os, new PgpCallback(true, os, REQUEST_CODE_DECRYPT_AND_VERIFY));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Encrypts a password file
*/
public void encrypt(Intent data) {
data.setAction(OpenPgpApi.ACTION_ENCRYPT);
// EXTRA_KEY_IDS requires long[]
long[] longKeys = new long[keyIDs.size()];
int i = 0;
for (String keyId : keyIDs) {
longKeys[i] = Long.valueOf(keyId);
++i;
}
data.putExtra(OpenPgpApi.EXTRA_KEY_IDS, longKeys);
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
String name = ((EditText) findViewById(R.id.crypto_password_file_edit)).getText().toString();
String pass = ((EditText) findViewById(R.id.crypto_password_edit)).getText().toString();
String extra = ((EditText) findViewById(R.id.crypto_extra_edit)).getText().toString();
if (name.isEmpty()) {
showToast(this.getResources().getString(R.string.file_toast_text));
return;
}
if (pass.isEmpty() && extra.isEmpty()) {
showToast(this.getResources().getString(R.string.empty_toast_text));
return;
}
ByteArrayInputStream is;
try {
is = new ByteArrayInputStream((pass + "\n" + extra).getBytes("UTF-8"));
ByteArrayOutputStream os = new ByteArrayOutputStream();
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
api.executeApiAsync(data, is, os, new PgpCallback(true, os, REQUEST_CODE_ENCRYPT));
} catch (Exception e) {
e.printStackTrace();
}
}
public void edit(Intent data) {
// exactly same as decrypt, only we want a different callback
data.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
try {
InputStream is = FileUtils.openInputStream(new File(getIntent().getExtras().getString("FILE_PATH")));
ByteArrayOutputStream os = new ByteArrayOutputStream();
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
api.executeApiAsync(data, is, os, new PgpCallback(true, os, REQUEST_CODE_EDIT));
} catch (Exception e) {
e.printStackTrace();
}
}
// TODO (low priority but still...) android M potential permissions crashes
@SuppressLint("SetTextI18n")
@Override
public void onBound(IOpenPgpService2 service) {
Log.i("PGP", "ISBOUND!!");
Bundle extra = getIntent().getExtras();
final String operation = extra.getString("Operation");
if (operation == null) {
return;
}
switch (operation) {
case "DECRYPT": {
setContentView(R.layout.decrypt_layout);
((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
String path = extra
.getString("FILE_PATH")
.replace(PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath(), "");
String cat = new File(path).getParentFile().getName();
((TextView) findViewById(R.id.crypto_password_category_decrypt)).setText(cat + "/");
decryptAndVerify(new Intent());
break;
}
case "ENCRYPT": {
setContentView(R.layout.encrypt_layout);
Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf");
((EditText) findViewById(R.id.crypto_password_edit)).setTypeface(monoTypeface);
((EditText) findViewById(R.id.crypto_extra_edit)).setTypeface(monoTypeface);
String cat = extra.getString("FILE_PATH");
cat = cat.replace(PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath(), "");
cat = cat + "/";
((TextView) findViewById(R.id.crypto_password_category_decrypt)).setText(cat);
break;
}
case "GET_KEY_ID":
getKeyIds(new Intent());
// setContentView(R.layout.key_id);
// if (!keyIDs.isEmpty()) {
// String keys = keyIDs.split(",").length > 1 ? keyIDs : keyIDs.split(",")[0];
// ((TextView) findViewById(R.id.crypto_key_ids)).setText(keys);
// }
break;
case "EDIT": {
setContentView(R.layout.decrypt_layout);
((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
String cat = new File(extra.getString("FILE_PATH").replace(PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath(), ""))
.getParentFile().getName();
((TextView) findViewById(R.id.crypto_password_category_decrypt)).setText(cat + "/");
edit(new Intent());
break;
}
case "SELECTFOLDER":
setContentView(R.layout.select_folder_layout);
selectFolder(getIntent());
break;
}
}
@Override
public void onError(Exception e) {
}
private class HoldToShowPasswordTransformation extends PasswordTransformationMethod implements View.OnTouchListener {
private final Runnable onToggle;
private boolean shown = false;
private HoldToShowPasswordTransformation(Button button, Runnable onToggle) {
this.onToggle = onToggle;
button.setOnTouchListener(this);
}
@Override
public CharSequence getTransformation(CharSequence charSequence, View view) {
return shown ? charSequence : super.getTransformation("12345", view);
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
shown = true;
onToggle.run();
break;
case MotionEvent.ACTION_UP:
shown = false;
onToggle.run();
break;
}
return false;
}
}
private void setTimer() {
// If a task already exist, let it finish without clearing the clipboard
if (delayTask != null) {
delayTask.setClearClipboard(false);
}
delayTask = new DelayShow();
delayTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}