Skip to content

Commit 5ec5483

Browse files
committed
Added an "Import missing key" button for the missing private keys situation.| #104.
1 parent 620bcd9 commit 5ec5483

File tree

4 files changed

+112
-10
lines changed

4 files changed

+112
-10
lines changed

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package com.flowcrypt.email.ui.activity.fragment;
88

99
import android.Manifest;
10+
import android.app.Activity;
1011
import android.content.Context;
1112
import android.content.Intent;
1213
import android.content.pm.PackageManager;
@@ -53,6 +54,7 @@
5354
import com.flowcrypt.email.model.results.LoaderResult;
5455
import com.flowcrypt.email.service.attachment.AttachmentDownloadManagerService;
5556
import com.flowcrypt.email.ui.activity.CreateMessageActivity;
57+
import com.flowcrypt.email.ui.activity.ImportPrivateKeyActivity;
5658
import com.flowcrypt.email.ui.activity.MessageDetailsActivity;
5759
import com.flowcrypt.email.ui.activity.base.BaseSyncActivity;
5860
import com.flowcrypt.email.ui.activity.fragment.base.BaseGmailFragment;
@@ -74,6 +76,8 @@
7476
*/
7577
public class MessageDetailsFragment extends BaseGmailFragment implements View.OnClickListener {
7678
private static final int REQUEST_CODE_REQUEST_WRITE_EXTERNAL_STORAGE = 100;
79+
private static final int REQUEST_CODE_START_IMPORT_KEY_ACTIVITY = 101;
80+
7781
private TextView textViewSenderAddress;
7882
private TextView textViewDate;
7983
private TextView textViewSubject;
@@ -145,6 +149,23 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
145149
}
146150
}
147151

152+
@Override
153+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
154+
switch (requestCode) {
155+
case REQUEST_CODE_START_IMPORT_KEY_ACTIVITY:
156+
switch (resultCode) {
157+
case Activity.RESULT_OK:
158+
Toast.makeText(getContext(), R.string.key_successfully_imported, Toast.LENGTH_SHORT).show();
159+
getLoaderManager().restartLoader(R.id.loader_id_load_message_info_from_database, null, this);
160+
break;
161+
}
162+
break;
163+
164+
default:
165+
super.onActivityResult(requestCode, resultCode, data);
166+
}
167+
}
168+
148169
@Override
149170
public View getContentView() {
150171
return layoutMessageParts;
@@ -502,8 +523,8 @@ public void onClick(View v) {
502523
}
503524

504525
private void updateMessageView() {
526+
layoutMessageParts.removeAllViews();
505527
if (!TextUtils.isEmpty(incomingMessageInfo.getHtmlMessage())) {
506-
layoutMessageParts.removeAllViews();
507528
EmailWebView emailWebView = new EmailWebView(getContext());
508529
emailWebView.configure();
509530

@@ -744,6 +765,9 @@ private View generatePgpMessagePart(MessagePartPgpMessage messagePartPgpMessage,
744765
(messagePartPgpMessage.getValue(), layoutInflater, formatErrorLayout));
745766
return formatErrorLayout;
746767

768+
case MISSING_PRIVATE_KEY:
769+
return generateMissingPrivateKeyLayout(messagePartPgpMessage, layoutInflater);
770+
747771
default:
748772
ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(
749773
R.layout.message_part_pgp_message_error, layoutMessageParts, false);
@@ -758,6 +782,36 @@ private View generatePgpMessagePart(MessagePartPgpMessage messagePartPgpMessage,
758782
} else return new TextView(getContext());
759783
}
760784

785+
/**
786+
* Generate a layout which describes the missing private keys situation.
787+
*
788+
* @param messagePartPgpMessage The {@link MessagePartPgpMessage} which contains info about an error.
789+
* @param layoutInflater The {@link LayoutInflater} instance.
790+
* @return Generated layout.
791+
*/
792+
@NonNull
793+
private View generateMissingPrivateKeyLayout(MessagePartPgpMessage messagePartPgpMessage,
794+
LayoutInflater layoutInflater) {
795+
ViewGroup missingPrivateKeyLayout = (ViewGroup) layoutInflater.inflate(
796+
R.layout.message_part_pgp_message_missing_private_key, layoutMessageParts, false);
797+
TextView textViewErrorMessage = missingPrivateKeyLayout.findViewById(R.id.textViewErrorMessage);
798+
textViewErrorMessage.setText(messagePartPgpMessage.getErrorMessage());
799+
800+
Button button = missingPrivateKeyLayout.findViewById(R.id.buttonImportPrivateKey);
801+
button.setOnClickListener(new View.OnClickListener() {
802+
@Override
803+
public void onClick(View v) {
804+
startActivityForResult(ImportPrivateKeyActivity.newIntent(
805+
getContext(), getString(R.string.import_private_key), true, ImportPrivateKeyActivity.class),
806+
REQUEST_CODE_START_IMPORT_KEY_ACTIVITY);
807+
}
808+
});
809+
810+
missingPrivateKeyLayout.addView(generateShowOriginalMessageLayout
811+
(messagePartPgpMessage.getValue(), layoutInflater, missingPrivateKeyLayout));
812+
return missingPrivateKeyLayout;
813+
}
814+
761815
/**
762816
* Generate a layout with switch button which will be regulate visibility of original message info.
763817
*

FlowCrypt/src/main/java/com/flowcrypt/email/ui/loader/DecryptMessageAsyncTaskLoader.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,29 @@ private MessagePartPgpMessage generateMessagePartPgpMessage(Js js, MessageBlock
225225
if (pgpDecrypted.isSuccess()) {
226226
value = pgpDecrypted.getString();
227227
} else if (!TextUtils.isEmpty(pgpDecrypted.getFormatError())) {
228-
errorMessage = getContext().getString(R.string.decrypt_error_message_badly_formatted) + "\n\n" +
229-
pgpDecrypted.getFormatError();
228+
errorMessage = getContext().getString(R.string.decrypt_error_message_badly_formatted,
229+
getContext().getString(R.string.app_name)) + "\n\n" + pgpDecrypted.getFormatError();
230230
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.FORMAT_ERROR;
231231
} else if (pgpDecrypted.getMissingPassphraseLongids() != null
232232
&& pgpDecrypted.getMissingPassphraseLongids().length > 0) {
233233
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.MISSING_PASS_PHRASES;
234-
} else if (Objects.equals(pgpDecrypted.countPotentiallyMatchingKeys(), pgpDecrypted.countAttempts())) {
234+
} else if (Objects.equals(pgpDecrypted.countPotentiallyMatchingKeys(), pgpDecrypted.countAttempts())
235+
&& Objects.equals(pgpDecrypted.countKeyMismatchErrors(), pgpDecrypted.countAttempts())) {
235236
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.MISSING_PRIVATE_KEY;
236-
errorMessage = getContext().getString(R.string.decrypt_error_could_not_open_message) +
237-
"\n\n" + getContext().getString(R.string.decrypt_error_single_sender);
237+
if (pgpDecrypted.getEncryptedForLongids().length > 1) {
238+
errorMessage = getContext().getString(R.string.decrypt_error_current_key_cannot_message);
239+
} else {
240+
errorMessage = getContext().getString(R.string.decrypt_error_could_not_open_message,
241+
getContext().getString(R.string.app_name)) + "\n\n" +
242+
getContext().getString(R.string.decrypt_error_single_sender);
243+
}
238244
} else if (pgpDecrypted.countUnsecureMdcErrors() > 0) {
239245
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.UNSECURED_MDC_ERROR;
240246
} else if (pgpDecrypted.getOtherErrors() != null && pgpDecrypted.getOtherErrors().length > 0) {
241247
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.OTHER_ERRORS;
242248
StringBuilder stringBuilder = new StringBuilder();
243-
stringBuilder.append(getContext().getString(R.string.decrypt_error_could_not_open_message));
249+
stringBuilder.append(getContext().getString(R.string.decrypt_error_could_not_open_message,
250+
getContext().getString(R.string.app_name)));
244251
stringBuilder.append("\n\n");
245252
stringBuilder.append(getContext().getString(R.string.decrypt_error_please_write_me));
246253
stringBuilder.append("\n\n");
@@ -253,7 +260,8 @@ private MessagePartPgpMessage generateMessagePartPgpMessage(Js js, MessageBlock
253260
errorMessage = stringBuilder.toString();
254261
} else {
255262
pgpMessageDecryptError = MessagePartPgpMessage.PgpMessageDecryptError.UNKNOWN_ERROR;
256-
errorMessage = getContext().getString(R.string.decrypt_error_could_not_open_message) +
263+
errorMessage = getContext().getString(R.string.decrypt_error_could_not_open_message,
264+
getContext().getString(R.string.app_name)) +
257265
"\n\n" + getContext().getString(R.string.decrypt_error_please_write_me);
258266
}
259267
} else {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Business Source License 1.0 © 2017 FlowCrypt Limited ([email protected]).
3+
~ Use limitations apply. See https://github.com/FlowCrypt/flowcrypt-android/blob/master/LICENSE
4+
~ Contributors: DenBond7
5+
-->
6+
7+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
8+
xmlns:tools="http://schemas.android.com/tools"
9+
android:layout_width="match_parent"
10+
android:layout_height="wrap_content"
11+
android:background="@drawable/bg_message_part_pgp_message_error"
12+
android:orientation="vertical">
13+
14+
<TextView
15+
android:id="@+id/textViewErrorMessage"
16+
android:layout_width="match_parent"
17+
android:layout_height="wrap_content"
18+
android:layout_marginBottom="@dimen/default_margin_medium"
19+
android:autoLink="web"
20+
android:textColor="@android:color/black"
21+
android:textIsSelectable="true"
22+
android:textSize="@dimen/default_text_size_medium"
23+
tools:text="At nihil sequi quo maiores molestiae consequatur. Id aut nam voluptate doloribus saepe consequatur molestias. Eos sunt est ipsam accusantium saepe doloribus veritatis.
24+
25+
26+
Recusandae velit sit veniam asperiores nisi. Eius tempore ab voluptatum dolorum nihil qui beatae. Et cum au" />
27+
28+
<Button
29+
android:id="@+id/buttonImportPrivateKey"
30+
style="@style/AppWidget.Button"
31+
android:layout_width="match_parent"
32+
android:layout_height="wrap_content"
33+
android:layout_marginBottom="@dimen/default_margin_content_small"
34+
android:layout_marginTop="@dimen/default_margin_content_small"
35+
android:text="@string/import_missing_key"
36+
android:theme="@style/AppWidget.Button.Green" />
37+
</LinearLayout>

FlowCrypt/src/main/res/values/strings.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,20 @@
203203
<string name="download_attachments_notification_channel">The download attachments notification channel</string>
204204
<string name="template_warning_max_attachments_size_for_decryption">The app cannot decrypt an attachment greater than %1$s</string>
205205
<string name="decrypt_error_js_tool_error">There is a JS tool error.</string>
206-
<string name="decrypt_error_could_not_open_message">Could not open this message with FlowCrypt.</string>
207-
<string name="decrypt_error_message_badly_formatted">Message is either badly formatted or not compatible with FlowCrypt.</string>
206+
<string name="decrypt_error_could_not_open_message">Could not open this message with %1$s.</string>
207+
<string name="decrypt_error_message_badly_formatted">Message is either badly formatted or not compatible with %1$s.</string>
208208
<string name="decrypt_error_please_write_me">Please write me at [email protected] so that I can fix it. I
209209
respond very promptly.</string>
210210
<string name="decrypt_error_single_sender">Normally, messages are encrypted for at least two people
211211
(sender and the receiver). It seems the sender encrypted this message manually for themselves,
212212
and forgot to add you as a receiver. Please ask them to send a new message.</string>
213+
<string name="decrypt_error_current_key_cannot_message">You current key cannot open this message. If you
214+
have any other keys available, you should import them now.</string>
213215
<string name="diagnostic_info">Diagnostic info</string>
214216
<string name="email_does_not_available_in_this_folder">Message not found, it may have been moved to another folder.</string>
215217
<string name="from">From</string>
216218
<string name="google_api_is_not_available">Error: Google API is not available</string>
217219
<string name="show_original_message">Show the original message</string>
218220
<string name="hide_original_message">Hide the original message</string>
221+
<string name="import_missing_key">Import missing key</string>
219222
</resources>

0 commit comments

Comments
 (0)