diff options
Diffstat (limited to 'src')
5 files changed, 189 insertions, 131 deletions
diff --git a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java index 2efdb8040..d23e3a88b 100644 --- a/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java +++ b/src/main/java/de/pixart/messenger/crypto/axolotl/AxolotlService.java @@ -77,6 +77,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { private final Map<Jid, Set<Integer>> deviceIds; private final Map<String, XmppAxolotlMessage> messageCache; private final FetchStatusMap fetchStatusMap; + private final Map<Jid, Boolean> fetchDeviceListStatus = new HashMap<>(); private final HashMap<Jid, List<OnDeviceIdsFetched>> fetchDeviceIdsMap = new HashMap<>(); private final SerialSingleThreadExecutor executor; private int numPublishTriesOnEmptyPep = 0; @@ -97,6 +98,20 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } } + private boolean hasErrorFetchingDeviceList(Jid jid) { + Boolean status = fetchDeviceListStatus.get(jid); + return status != null && !status; + } + + public boolean hasErrorFetchingDeviceList(List<Jid> jids) { + for(Jid jid : jids) { + if (hasErrorFetchingDeviceList(jid)) { + return true; + } + } + return false; + } + public boolean fetchMapHasErrors(List<Jid> jids) { for (Jid jid : jids) { if (deviceIds.get(jid) != null) { @@ -361,6 +376,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { public void clearErrorsInFetchStatusMap(Jid jid) { fetchStatusMap.clearErrorFor(jid); + fetchDeviceListStatus.remove(jid); } public void regenerateKeys(boolean wipeOther) { @@ -368,6 +384,7 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { sessions.clear(); fetchStatusMap.clear(); fetchDeviceIdsMap.clear(); + fetchDeviceListStatus.clear(); publishBundlesIfNeeded(true, wipeOther); } @@ -960,26 +977,29 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { this.fetchDeviceIdsMap.put(jid, callbacks); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": fetching device ids for " + jid); IqPacket packet = mXmppConnectionService.getIqGenerator().retrieveDeviceIds(jid); - mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - synchronized (fetchDeviceIdsMap) { - List<OnDeviceIdsFetched> callbacks = fetchDeviceIdsMap.remove(jid); - if (packet.getType() == IqPacket.TYPE.RESULT) { - Element item = mXmppConnectionService.getIqParser().getItem(packet); - Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); - registerDevices(jid, deviceIds); - if (callbacks != null) { - for (OnDeviceIdsFetched callback : callbacks) { - callback.fetched(jid, deviceIds); - } + mXmppConnectionService.sendIqPacket(account, packet, (account, response) -> { + synchronized (fetchDeviceIdsMap) { + List<OnDeviceIdsFetched> callbacks1 = fetchDeviceIdsMap.remove(jid); + if (response.getType() == IqPacket.TYPE.RESULT) { + fetchDeviceListStatus.put(jid, true); + Element item = mXmppConnectionService.getIqParser().getItem(response); + Set<Integer> deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); + registerDevices(jid, deviceIds); + if (callbacks1 != null) { + for (OnDeviceIdsFetched callback1 : callbacks1) { + callback1.fetched(jid, deviceIds); } + } + } else { + if (response.getType() == IqPacket.TYPE.TIMEOUT) { + fetchDeviceListStatus.remove(jid); } else { - Log.d(Config.LOGTAG, packet.toString()); - if (callbacks != null) { - for (OnDeviceIdsFetched callback : callbacks) { - callback.fetched(jid, null); - } + fetchDeviceListStatus.put(jid, false); + } + Log.d(Config.LOGTAG, response.toString()); + if (callbacks1 != null) { + for (OnDeviceIdsFetched callback1 : callbacks1) { + callback1.fetched(jid, null); } } } @@ -993,14 +1013,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { final ArrayList<Jid> unfinishedJids = new ArrayList<>(jids); synchronized (unfinishedJids) { for (Jid jid : unfinishedJids) { - fetchDeviceIds(jid, new OnDeviceIdsFetched() { - @Override - public void fetched(Jid jid, Set<Integer> deviceIds) { - synchronized (unfinishedJids) { - unfinishedJids.remove(jid); - if (unfinishedJids.size() == 0 && callback != null) { - callback.fetched(); - } + fetchDeviceIds(jid, (j, deviceIds) -> { + synchronized (unfinishedJids) { + unfinishedJids.remove(j); + if (unfinishedJids.size() == 0 && callback != null) { + callback.fetched(); } } }); diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index ddf7d6644..70f88b227 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -910,11 +910,11 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke break; case Message.ENCRYPTION_AXOLOTL: if (!trustKeysIfNeeded(REQUEST_TRUST_KEYS_TEXT)) { - sendAxolotlMessage(message); + sendMessage(message); } break; default: - sendPlainTextMessage(message); + sendMessage(message); } } @@ -987,7 +987,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke case REQUEST_TRUST_KEYS_TEXT: final String body = binding.textinput.getText().toString(); Message message = new Message(conversation, body, conversation.getNextEncryption()); - sendAxolotlMessage(message); + sendMessage(message); break; case REQUEST_TRUST_KEYS_MENU: int choice = data.getIntExtra("choice", ATTACHMENT_CHOICE_INVALID); @@ -2578,7 +2578,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke return this.binding.searchfield.getVisibility() == View.VISIBLE; } - protected void sendPlainTextMessage(Message message) { + protected void sendMessage(Message message) { activity.xmppConnectionService.sendMessage(message); messageSent(); } @@ -2697,11 +2697,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke builder.create().show(); } - protected void sendAxolotlMessage(final Message message) { - activity.xmppConnectionService.sendMessage(message); - messageSent(); - } - protected void sendOtrMessage(final Message message) { final ConversationsActivity activity = (ConversationsActivity) getActivity(); final XmppConnectionService xmppService = activity.xmppConnectionService; diff --git a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java index be4c86549..0a2dade8d 100644 --- a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java +++ b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java @@ -1,5 +1,6 @@ package de.pixart.messenger.ui; +import android.app.AlertDialog; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; @@ -10,7 +11,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; -import android.widget.CompoundButton; import android.widget.Toast; import org.whispersystems.libsignal.IdentityKey; @@ -29,7 +29,9 @@ import de.pixart.messenger.crypto.axolotl.FingerprintStatus; import de.pixart.messenger.databinding.ActivityTrustKeysBinding; import de.pixart.messenger.databinding.KeysCardBinding; import de.pixart.messenger.entities.Account; +import de.pixart.messenger.entities.Contact; import de.pixart.messenger.entities.Conversation; +import de.pixart.messenger.entities.Message; import de.pixart.messenger.utils.CryptoHelper; import de.pixart.messenger.utils.IrregularUnicodeDetector; import de.pixart.messenger.utils.XmppUri; @@ -37,33 +39,21 @@ import de.pixart.messenger.xmpp.OnKeyStatusUpdated; import rocks.xmpp.addr.Jid; public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdated { + private final Map<String, Boolean> ownKeysToTrust = new HashMap<>(); + private final Map<Jid, Map<String, Boolean>> foreignKeysToTrust = new HashMap<>(); + private final OnClickListener mCancelButtonListener = v -> { + setResult(RESULT_CANCELED); + finish(); + }; private List<Jid> contactJids; - private Account mAccount; private Conversation mConversation; - + private final OnClickListener mSaveButtonListener = v -> { + commitTrusts(); + finishOk(false); + }; private AtomicBoolean mUseCameraHintShown = new AtomicBoolean(false); - private AxolotlService.FetchStatus lastFetchReport = AxolotlService.FetchStatus.SUCCESS; - - private final Map<String, Boolean> ownKeysToTrust = new HashMap<>(); - private final Map<Jid,Map<String, Boolean>> foreignKeysToTrust = new HashMap<>(); - - private final OnClickListener mSaveButtonListener = new OnClickListener() { - @Override - public void onClick(View v) { - commitTrusts(); - finishOk(); - } - }; - - private final OnClickListener mCancelButtonListener = new OnClickListener() { - @Override - public void onClick(View v) { - setResult(RESULT_CANCELED); - finish(); - } - }; private Toast mUseCameraHintToast = null; private ActivityTrustKeysBinding binding; @@ -76,9 +66,9 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.binding = DataBindingUtil.setContentView(this,R.layout.activity_trust_keys); + this.binding = DataBindingUtil.setContentView(this, R.layout.activity_trust_keys); this.contactJids = new ArrayList<>(); - for(String jid : getIntent().getStringArrayExtra("contacts")) { + for (String jid : getIntent().getStringArrayExtra("contacts")) { try { this.contactJids.add(Jid.of(jid)); } catch (IllegalArgumentException e) { @@ -96,7 +86,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat } if (savedInstanceState != null) { - mUseCameraHintShown.set(savedInstanceState.getBoolean("camera_hint_shown",false)); + mUseCameraHintShown.set(savedInstanceState.getBoolean("camera_hint_shown", false)); } } @@ -115,9 +105,9 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat } private void showCameraToast() { - mUseCameraHintToast = Toast.makeText(this,R.string.use_camera_icon_to_scan_barcode,Toast.LENGTH_LONG); + mUseCameraHintToast = Toast.makeText(this, R.string.use_camera_icon_to_scan_barcode, Toast.LENGTH_LONG); ActionBar actionBar = getSupportActionBar(); - mUseCameraHintToast.setGravity(Gravity.TOP | Gravity.END, 0 ,actionBar == null ? 0 : actionBar.getHeight()); + mUseCameraHintToast.setGravity(Gravity.TOP | Gravity.END, 0, actionBar == null ? 0 : actionBar.getHeight()); mUseCameraHintToast.show(); } @@ -129,6 +119,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat Toast.makeText(this, R.string.please_wait_for_keys_to_be_fetched, Toast.LENGTH_SHORT).show(); } else { ScanActivity.scan(this); + //new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE")); return true; } } @@ -149,19 +140,19 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat && mAccount != null && uri.hasFingerprints() && mAccount.getAxolotlService().getCryptoTargets(mConversation).contains(uri.getJid())) { - boolean performedVerification = xmppConnectionService.verifyFingerprints(mAccount.getRoster().getContact(uri.getJid()),uri.getFingerprints()); + boolean performedVerification = xmppConnectionService.verifyFingerprints(mAccount.getRoster().getContact(uri.getJid()), uri.getFingerprints()); boolean keys = reloadFingerprints(); if (performedVerification && !keys && !hasNoOtherTrustedKeys() && !hasPendingKeyFetches()) { - Toast.makeText(this,R.string.all_omemo_keys_have_been_verified, Toast.LENGTH_SHORT).show(); - finishOk(); + Toast.makeText(this, R.string.all_omemo_keys_have_been_verified, Toast.LENGTH_SHORT).show(); + finishOk(false); return; } else if (performedVerification) { - Toast.makeText(this,R.string.verified_fingerprints,Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.verified_fingerprints, Toast.LENGTH_SHORT).show(); } } else { reloadFingerprints(); - Log.d(Config.LOGTAG,"xmpp uri was: "+uri.getJid()+" has Fingerprints: "+Boolean.toString(uri.hasFingerprints())); - Toast.makeText(this,R.string.barcode_does_not_contain_fingerprints_for_this_conversation,Toast.LENGTH_SHORT).show(); + Log.d(Config.LOGTAG, "xmpp uri was: " + uri.getJid() + " has Fingerprints: " + Boolean.toString(uri.hasFingerprints())); + Toast.makeText(this, R.string.barcode_does_not_contain_fingerprints_for_this_conversation, Toast.LENGTH_SHORT).show(); } populateView(); } @@ -172,16 +163,13 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat binding.foreignKeys.removeAllViews(); boolean hasOwnKeys = false; boolean hasForeignKeys = false; - for(final String fingerprint : ownKeysToTrust.keySet()) { + for (final String fingerprint : ownKeysToTrust.keySet()) { hasOwnKeys = true; addFingerprintRowWithListeners(binding.ownKeysDetails, mAccount, fingerprint, false, FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)), false, false, - new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - ownKeysToTrust.put(fingerprint, isChecked); - // own fingerprints have no impact on locked status. - } + (buttonView, isChecked) -> { + ownKeysToTrust.put(fingerprint, isChecked); + // own fingerprints have no impact on locked status. } ); } @@ -189,7 +177,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat synchronized (this.foreignKeysToTrust) { for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) { hasForeignKeys = true; - KeysCardBinding keysCardBinding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.keys_card, binding.foreignKeys,false); + KeysCardBinding keysCardBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.keys_card, binding.foreignKeys, false); final Jid jid = entry.getKey(); keysCardBinding.foreignKeysTitle.setText(IrregularUnicodeDetector.style(this, jid)); keysCardBinding.foreignKeysTitle.setOnClickListener(v -> switchToContactDetails(mAccount.getRoster().getContact(jid))); @@ -228,23 +216,30 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat binding.ownKeysTitle.setText(mAccount.getJid().asBareJid().toString()); binding.ownKeysCard.setVisibility(hasOwnKeys ? View.VISIBLE : View.GONE); binding.foreignKeys.setVisibility(hasForeignKeys ? View.VISIBLE : View.GONE); - if(hasPendingKeyFetches()) { + if (hasPendingKeyFetches()) { setFetching(); lock(); } else { if (!hasForeignKeys && hasNoOtherTrustedKeys()) { binding.keyErrorMessageCard.setVisibility(View.VISIBLE); - if (lastFetchReport == AxolotlService.FetchStatus.ERROR - || mAccount.getAxolotlService().fetchMapHasErrors(contactJids)) { - if (anyWithoutMutualPresenceSubscription(contactJids)) { - binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust_presence); - } else { - binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust_server_error); - } + boolean lastReportWasError = lastFetchReport == AxolotlService.FetchStatus.ERROR; + boolean errorFetchingBundle = mAccount.getAxolotlService().fetchMapHasErrors(contactJids); + boolean errorFetchingDeviceList = mAccount.getAxolotlService().hasErrorFetchingDeviceList(contactJids); + boolean anyWithoutMutualPresenceSubscription = anyWithoutMutualPresenceSubscription(contactJids); + if (errorFetchingDeviceList) { + binding.keyErrorMessage.setVisibility(View.VISIBLE); + binding.keyErrorMessage.setText(R.string.error_trustkey_device_list); + } else if (errorFetchingBundle || lastReportWasError) { + binding.keyErrorMessage.setVisibility(View.VISIBLE); + binding.keyErrorMessage.setText(R.string.error_trustkey_bundle); } else { - binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust); + binding.keyErrorMessage.setVisibility(View.GONE); } + this.binding.keyErrorHintMutual.setVisibility(anyWithoutMutualPresenceSubscription ? View.VISIBLE : View.GONE); + Contact contact = mAccount.getRoster().getContact(contactJids.get(0)); + binding.keyErrorGeneral.setText(getString(R.string.error_trustkey_general, contact.getDisplayName())); binding.ownKeysDetails.removeAllViews(); + binding.disableButton.setOnClickListener(this::disableEncryptionDialog); binding.ownKeysCard.setVisibility(View.GONE); binding.foreignKeys.removeAllViews(); binding.foreignKeys.setVisibility(View.GONE); @@ -254,8 +249,21 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat } } - private boolean anyWithoutMutualPresenceSubscription(List<Jid> contactJids){ - for(Jid jid : contactJids) { + private void disableEncryptionDialog(View view) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.disable_encryption); + builder.setMessage(R.string.disable_encryption_message); + builder.setPositiveButton(R.string.disable_now, (dialog, which) -> { + mConversation.setNextEncryption(Message.ENCRYPTION_NONE); + xmppConnectionService.updateConversation(mConversation); + finishOk(true); + }); + builder.setNegativeButton(R.string.cancel, null); + builder.create().show(); + } + + private boolean anyWithoutMutualPresenceSubscription(List<Jid> contactJids) { + for (Jid jid : contactJids) { if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) { return true; } @@ -275,13 +283,13 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat } private boolean reloadFingerprints() { - List<Jid> acceptedTargets = mConversation == null ? new ArrayList<Jid>() : mConversation.getAcceptedCryptoTargets(); + List<Jid> acceptedTargets = mConversation == null ? new ArrayList<>() : mConversation.getAcceptedCryptoTargets(); ownKeysToTrust.clear(); AxolotlService service = this.mAccount.getAxolotlService(); Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided()); - for(final IdentityKey identityKey : ownKeysSet) { + for (final IdentityKey identityKey : ownKeysSet) { final String fingerprint = CryptoHelper.bytesToHex(identityKey.getPublicKey().serialize()); - if(!ownKeysToTrust.containsKey(fingerprint)) { + if (!ownKeysToTrust.containsKey(fingerprint)) { ownKeysToTrust.put(fingerprint, false); } } @@ -342,25 +350,22 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat final boolean keysToTrust = reloadFingerprints(); if (report != null) { lastFetchReport = report; - runOnUiThread(new Runnable() { - @Override - public void run() { - if (mUseCameraHintToast != null && !keysToTrust) { - mUseCameraHintToast.cancel(); - } - switch (report) { - case ERROR: - Toast.makeText(TrustKeysActivity.this,R.string.error_fetching_omemo_key,Toast.LENGTH_SHORT).show(); - break; - case SUCCESS_TRUSTED: - Toast.makeText(TrustKeysActivity.this,R.string.blindly_trusted_omemo_keys,Toast.LENGTH_LONG).show(); - break; - case SUCCESS_VERIFIED: - Toast.makeText(TrustKeysActivity.this, - Config.X509_VERIFICATION ? R.string.verified_omemo_key_with_certificate : R.string.all_omemo_keys_have_been_verified, - Toast.LENGTH_LONG).show(); - break; - } + runOnUiThread(() -> { + if (mUseCameraHintToast != null && !keysToTrust) { + mUseCameraHintToast.cancel(); + } + switch (report) { + case ERROR: + Toast.makeText(TrustKeysActivity.this, R.string.error_fetching_omemo_key, Toast.LENGTH_SHORT).show(); + break; + case SUCCESS_TRUSTED: + Toast.makeText(TrustKeysActivity.this, R.string.blindly_trusted_omemo_keys, Toast.LENGTH_LONG).show(); + break; + case SUCCESS_VERIFIED: + Toast.makeText(TrustKeysActivity.this, + Config.X509_VERIFICATION ? R.string.verified_omemo_key_with_certificate : R.string.all_omemo_keys_have_been_verified, + Toast.LENGTH_LONG).show(); + break; } }); @@ -368,25 +373,21 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat if (keysToTrust || hasPendingKeyFetches() || hasNoOtherTrustedKeys()) { refreshUi(); } else { - runOnUiThread(new Runnable() { - @Override - public void run() { - finishOk(); - } - }); + runOnUiThread(() -> finishOk(false)); } } - private void finishOk() { + private void finishOk(boolean disabled) { Intent data = new Intent(); data.putExtra("choice", getIntent().getIntExtra("choice", ConversationFragment.ATTACHMENT_CHOICE_INVALID)); + data.putExtra("disabled", disabled); setResult(RESULT_OK, data); finish(); } private void commitTrusts() { - for(final String fingerprint :ownKeysToTrust.keySet()) { + for (final String fingerprint : ownKeysToTrust.keySet()) { mAccount.getAxolotlService().setFingerprintTrust( fingerprint, FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint))); diff --git a/src/main/res/layout/activity_trust_keys.xml b/src/main/res/layout/activity_trust_keys.xml index f52d0fe99..431348f19 100644 --- a/src/main/res/layout/activity_trust_keys.xml +++ b/src/main/res/layout/activity_trust_keys.xml @@ -30,22 +30,60 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" - android:padding="@dimen/card_padding_regular"> + android:orientation="vertical"> - <TextView - android:id="@+id/key_error_message_title" - android:layout_width="wrap_content" + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/error_trustkeys_title" - android:textAppearance="@style/TextAppearance.AppCompat.Title" /> + android:orientation="vertical" + android:padding="@dimen/card_padding_regular"> + + <TextView + android:id="@+id/key_error_message_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="8sp" + android:text="@string/error_trustkeys_title" + android:textAppearance="@style/TextAppearance.AppCompat.Title" /> + + <TextView + android:id="@+id/key_error_message" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Subhead" /> + + <TextView + android:id="@+id/key_error_general" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Conversations.Body1" /> + + <TextView + android:id="@+id/key_error_hint_mutual" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8sp" + android:text="@string/error_trustkey_hint_mutual" + android:textAppearance="@style/TextAppearance.Conversations.Body1.Secondary" /> + </LinearLayout> - <TextView - android:id="@+id/key_error_message" - android:layout_width="wrap_content" + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="8dp" - android:textAppearance="@style/TextAppearance.AppCompat.Title" /> + android:layout_gravity="right" + android:gravity="right"> + + <Button + android:id="@+id/disable_button" + style="?android:attr/borderlessButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="0dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:text="@string/disable_encryption" + android:textColor="@color/accent" /> + </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index f5a6d80be..c2cb55f91 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -349,7 +349,7 @@ <string name="distrust_omemo_key_text">Are you sure you want to remove the verification for this device?\nThis device and messages coming from that device will be marked as untrusted.</string> <string name="error_no_keys_to_trust_server_error">There are no usable keys available for this contact.\nFetching new keys from the server has been unsuccessful. Maybe there is something wrong with your contacts server.</string> <string name="error_no_keys_to_trust">There are no usable keys available for this contact. If you have purged any of their keys, they need to generate new ones.</string> - <string name="error_trustkeys_title">Error</string> + <string name="error_trustkeys_title">Something went wrong</string> <string name="fetching_history_from_server">Fetching history from server</string> <string name="no_more_history_on_server">No more history on server</string> <string name="updating">Updating…</string> @@ -764,4 +764,11 @@ <string name="change_presence">Manage availability manually</string> <string name="pref_automatically_delete_messages_description">Automatically delete messages from this device that are older than the configured time frame.</string> <string name="pref_automatically_delete_messages">Automatic message deletion</string> + <string name="disable_encryption">Disable encryption</string> + <string name="error_trustkey_general">Conversations is unable to send encrypted messages to %1$s. This may be due to your contact using an outdated server or client that can not handle OMEMO.</string> + <string name="error_trustkey_device_list">Unable to fetch device list</string> + <string name="error_trustkey_bundle">Unable to fetch device bundles</string> + <string name="error_trustkey_hint_mutual">Hint: In some cases this can be fixed by adding each other your contact lists.</string> + <string name="disable_encryption_message">Are you sure you want to disable OMEMO encryption for this conversation?\nThis will allow your server administrator to read your messages, but it might be the only way to communicate with people using outdated clients.</string> + <string name="disable_now">Disable now</string> </resources> |