Support import from application/autocrypt-setup type
This commit is contained in:
@@ -454,6 +454,14 @@
|
|||||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
|
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
|
||||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
|
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\..*\\.bin" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter android:label="@string/intent_autocrypt_setup">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data android:mimeType="application/autocrypt-setup" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.UploadKeyActivity"
|
android:name=".ui.UploadKeyActivity"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public abstract class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||||||
|
|
||||||
abstract boolean isAllowSymmetricDecryption();
|
abstract boolean isAllowSymmetricDecryption();
|
||||||
abstract boolean isDecryptMetadataOnly();
|
abstract boolean isDecryptMetadataOnly();
|
||||||
|
abstract boolean isAutocryptSetup();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract List<Long> getAllowedKeyIds();
|
abstract List<Long> getAllowedKeyIds();
|
||||||
@@ -55,7 +56,8 @@ public abstract class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new AutoValue_PgpDecryptVerifyInputParcel.Builder()
|
return new AutoValue_PgpDecryptVerifyInputParcel.Builder()
|
||||||
.setAllowSymmetricDecryption(false)
|
.setAllowSymmetricDecryption(false)
|
||||||
.setDecryptMetadataOnly(false);
|
.setDecryptMetadataOnly(false)
|
||||||
|
.setAutocryptSetup(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoValue.Builder
|
@AutoValue.Builder
|
||||||
@@ -68,6 +70,7 @@ public abstract class PgpDecryptVerifyInputParcel implements Parcelable {
|
|||||||
public abstract Builder setDecryptMetadataOnly(boolean decryptMetadataOnly);
|
public abstract Builder setDecryptMetadataOnly(boolean decryptMetadataOnly);
|
||||||
public abstract Builder setDetachedSignature(byte[] detachedSignature);
|
public abstract Builder setDetachedSignature(byte[] detachedSignature);
|
||||||
public abstract Builder setSenderAddress(String senderAddress);
|
public abstract Builder setSenderAddress(String senderAddress);
|
||||||
|
public abstract Builder setAutocryptSetup(boolean isAutocryptSetup);
|
||||||
|
|
||||||
public abstract Builder setAllowedKeyIds(List<Long> allowedKeyIds);
|
public abstract Builder setAllowedKeyIds(List<Long> allowedKeyIds);
|
||||||
abstract List<Long> getAllowedKeyIds();
|
abstract List<Long> getAllowedKeyIds();
|
||||||
|
|||||||
@@ -315,7 +315,12 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
|||||||
if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 2) {
|
if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 2) {
|
||||||
customRequiredInputParcel = RequiredInputParcel.createRequiredBackupCode();
|
customRequiredInputParcel = RequiredInputParcel.createRequiredBackupCode();
|
||||||
} else if (PASSPHRASE_FORMAT_NUMERIC9X4.equalsIgnoreCase(armorHeaders.passphraseFormat)) {
|
} else if (PASSPHRASE_FORMAT_NUMERIC9X4.equalsIgnoreCase(armorHeaders.passphraseFormat)) {
|
||||||
customRequiredInputParcel = RequiredInputParcel.createRequiredNumeric9x4(armorHeaders.passphraseBegin);
|
if (input.isAutocryptSetup()) {
|
||||||
|
customRequiredInputParcel =
|
||||||
|
RequiredInputParcel.createRequiredNumeric9x4Autocrypt(armorHeaders.passphraseBegin);
|
||||||
|
} else {
|
||||||
|
customRequiredInputParcel = RequiredInputParcel.createRequiredNumeric9x4(armorHeaders.passphraseBegin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenPgpDecryptionResultBuilder decryptionResultBuilder = new OpenPgpDecryptionResultBuilder();
|
OpenPgpDecryptionResultBuilder decryptionResultBuilder = new OpenPgpDecryptionResultBuilder();
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
|
|
||||||
public enum RequiredInputType {
|
public enum RequiredInputType {
|
||||||
PASSPHRASE, PASSPHRASE_SYMMETRIC, PASSPHRASE_AUTH,
|
PASSPHRASE, PASSPHRASE_SYMMETRIC, PASSPHRASE_AUTH,
|
||||||
BACKUP_CODE, NUMERIC_9X4,
|
BACKUP_CODE, NUMERIC_9X4, NUMERIC_9X4_AUTOCRYPT,
|
||||||
SECURITY_TOKEN_SIGN, SECURITY_TOKEN_AUTH, SECURITY_TOKEN_DECRYPT,
|
SECURITY_TOKEN_SIGN, SECURITY_TOKEN_AUTH, SECURITY_TOKEN_DECRYPT,
|
||||||
SECURITY_TOKEN_MOVE_KEY_TO_CARD, SECURITY_TOKEN_RESET_CARD,
|
SECURITY_TOKEN_MOVE_KEY_TO_CARD, SECURITY_TOKEN_RESET_CARD,
|
||||||
ENABLE_ORBOT, UPLOAD_FAIL_RETRY
|
ENABLE_ORBOT, UPLOAD_FAIL_RETRY
|
||||||
@@ -193,6 +193,12 @@ public class RequiredInputParcel implements Parcelable {
|
|||||||
inputData, null, null, (long[]) null, null);
|
inputData, null, null, (long[]) null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RequiredInputParcel createRequiredNumeric9x4Autocrypt(String beginChars) {
|
||||||
|
byte[][] inputData = beginChars != null ? new byte[][] { beginChars.getBytes() } : null;
|
||||||
|
return new RequiredInputParcel(RequiredInputType.NUMERIC_9X4_AUTOCRYPT,
|
||||||
|
inputData, null, null, (long[]) null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static RequiredInputParcel createRequiredPassphrase(
|
public static RequiredInputParcel createRequiredPassphrase(
|
||||||
RequiredInputParcel req) {
|
RequiredInputParcel req) {
|
||||||
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
|
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
|||||||
|
|
||||||
|
|
||||||
public class DecryptActivity extends BaseActivity {
|
public class DecryptActivity extends BaseActivity {
|
||||||
|
public static final String APPLICATION_AUTOCRYPT_SETUP = "application/autocrypt-setup";
|
||||||
|
|
||||||
/* Intents */
|
/* Intents */
|
||||||
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = "DECRYPT_DATA_CLIPBOARD";
|
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = "DECRYPT_DATA_CLIPBOARD";
|
||||||
@@ -84,6 +85,7 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
|
|
||||||
// depending on the data source, we may or may not be able to delete the original file
|
// depending on the data source, we may or may not be able to delete the original file
|
||||||
boolean canDelete = false;
|
boolean canDelete = false;
|
||||||
|
boolean isAutocryptSetup = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -160,6 +162,9 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
case Constants.DECRYPT_DATA:
|
case Constants.DECRYPT_DATA:
|
||||||
default:
|
default:
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
|
|
||||||
|
isAutocryptSetup = APPLICATION_AUTOCRYPT_SETUP.equalsIgnoreCase(intent.getType());
|
||||||
|
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
|
|
||||||
if ("com.android.email.attachmentprovider".equals(uri.getHost())) {
|
if ("com.android.email.attachmentprovider".equals(uri.getHost())) {
|
||||||
@@ -187,7 +192,7 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayListFragment(uris, canDelete);
|
displayListFragment(uris, canDelete, isAutocryptSetup);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +216,9 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
return tempFile;
|
return tempFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayListFragment(ArrayList<Uri> inputUris, boolean canDelete) {
|
public void displayListFragment(ArrayList<Uri> inputUris, boolean canDelete, boolean isAutocryptSetup) {
|
||||||
|
|
||||||
DecryptListFragment frag = DecryptListFragment.newInstance(inputUris, canDelete);
|
DecryptListFragment frag = DecryptListFragment.newInstance(inputUris, canDelete, isAutocryptSetup);
|
||||||
|
|
||||||
FragmentManager fragMan = getSupportFragmentManager();
|
FragmentManager fragMan = getSupportFragmentManager();
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ public class DecryptListFragment
|
|||||||
public static final String ARG_CANCELLED_URIS = "cancelled_uris";
|
public static final String ARG_CANCELLED_URIS = "cancelled_uris";
|
||||||
public static final String ARG_RESULTS = "results";
|
public static final String ARG_RESULTS = "results";
|
||||||
public static final String ARG_CAN_DELETE = "can_delete";
|
public static final String ARG_CAN_DELETE = "can_delete";
|
||||||
|
public static final String ARG_IS_AUTOCRYPT_SETUP = "is_autocrypt_setup";
|
||||||
|
|
||||||
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
||||||
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
|
private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12;
|
||||||
@@ -136,6 +137,7 @@ public class DecryptListFragment
|
|||||||
|
|
||||||
private Uri mCurrentInputUri;
|
private Uri mCurrentInputUri;
|
||||||
private boolean mCanDelete;
|
private boolean mCanDelete;
|
||||||
|
private boolean mIsAutocryptSetup;
|
||||||
|
|
||||||
private DecryptFilesAdapter mAdapter;
|
private DecryptFilesAdapter mAdapter;
|
||||||
private Uri mCurrentSaveFileUri;
|
private Uri mCurrentSaveFileUri;
|
||||||
@@ -143,12 +145,13 @@ public class DecryptListFragment
|
|||||||
/**
|
/**
|
||||||
* Creates new instance of this fragment
|
* Creates new instance of this fragment
|
||||||
*/
|
*/
|
||||||
public static DecryptListFragment newInstance(@NonNull ArrayList<Uri> uris, boolean canDelete) {
|
public static DecryptListFragment newInstance(@NonNull ArrayList<Uri> uris, boolean canDelete, boolean isAutocryptSetup) {
|
||||||
DecryptListFragment frag = new DecryptListFragment();
|
DecryptListFragment frag = new DecryptListFragment();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelableArrayList(ARG_INPUT_URIS, uris);
|
args.putParcelableArrayList(ARG_INPUT_URIS, uris);
|
||||||
args.putBoolean(ARG_CAN_DELETE, canDelete);
|
args.putBoolean(ARG_CAN_DELETE, canDelete);
|
||||||
|
args.putBoolean(ARG_IS_AUTOCRYPT_SETUP, isAutocryptSetup);
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
|
|
||||||
return frag;
|
return frag;
|
||||||
@@ -205,6 +208,7 @@ public class DecryptListFragment
|
|||||||
outState.putParcelable(ARG_OUTPUT_URIS, new ParcelableHashMap<>(mInputDataResults));
|
outState.putParcelable(ARG_OUTPUT_URIS, new ParcelableHashMap<>(mInputDataResults));
|
||||||
outState.putParcelableArrayList(ARG_CANCELLED_URIS, mCancelledInputUris);
|
outState.putParcelableArrayList(ARG_CANCELLED_URIS, mCancelledInputUris);
|
||||||
outState.putBoolean(ARG_CAN_DELETE, mCanDelete);
|
outState.putBoolean(ARG_CAN_DELETE, mCanDelete);
|
||||||
|
outState.putBoolean(ARG_IS_AUTOCRYPT_SETUP, mIsAutocryptSetup);
|
||||||
|
|
||||||
// this does not save mCurrentInputUri - if anything is being
|
// this does not save mCurrentInputUri - if anything is being
|
||||||
// processed at fragment recreation time, the operation in
|
// processed at fragment recreation time, the operation in
|
||||||
@@ -222,6 +226,7 @@ public class DecryptListFragment
|
|||||||
ParcelableHashMap<Uri, InputDataResult> results = args.getParcelable(ARG_RESULTS);
|
ParcelableHashMap<Uri, InputDataResult> results = args.getParcelable(ARG_RESULTS);
|
||||||
|
|
||||||
mCanDelete = args.getBoolean(ARG_CAN_DELETE, false);
|
mCanDelete = args.getBoolean(ARG_CAN_DELETE, false);
|
||||||
|
mIsAutocryptSetup = args.getBoolean(ARG_IS_AUTOCRYPT_SETUP, false);
|
||||||
|
|
||||||
displayInputUris(inputUris, cancelledUris,
|
displayInputUris(inputUris, cancelledUris,
|
||||||
results != null ? results.getMap() : null
|
results != null ? results.getMap() : null
|
||||||
@@ -638,11 +643,14 @@ public class DecryptListFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
PgpDecryptVerifyInputParcel.Builder decryptInput = PgpDecryptVerifyInputParcel.builder()
|
PgpDecryptVerifyInputParcel.Builder decryptInput = PgpDecryptVerifyInputParcel.builder()
|
||||||
.setAllowSymmetricDecryption(true);
|
.setAllowSymmetricDecryption(true)
|
||||||
|
.setAutocryptSetup(mIsAutocryptSetup);
|
||||||
return InputDataParcel.createInputDataParcel(mCurrentInputUri, decryptInput.build());
|
return InputDataParcel.createInputDataParcel(mCurrentInputUri, decryptInput.build());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
|
* Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|||||||
@@ -203,7 +203,8 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
|||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4) {
|
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4 ||
|
||||||
|
mRequiredInput.mType == RequiredInputType.NUMERIC_9X4_AUTOCRYPT) {
|
||||||
LayoutInflater inflater = LayoutInflater.from(theme);
|
LayoutInflater inflater = LayoutInflater.from(theme);
|
||||||
View view = inflater.inflate(R.layout.passphrase_dialog_numeric_9x4, null);
|
View view = inflater.inflate(R.layout.passphrase_dialog_numeric_9x4, null);
|
||||||
alert.setView(view);
|
alert.setView(view);
|
||||||
@@ -234,9 +235,14 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
|||||||
setupEditTextFocusNext(mBackupCodeEditText, false);
|
setupEditTextFocusNext(mBackupCodeEditText, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4_AUTOCRYPT) {
|
||||||
|
TextView promptText = view.findViewById(R.id.passphrase_text);
|
||||||
|
promptText.setText(R.string.passphrase_transfer_autocrypt);
|
||||||
|
}
|
||||||
|
|
||||||
AlertDialog dialog = alert.create();
|
AlertDialog dialog = alert.create();
|
||||||
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
|
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
|
||||||
activity.getString(R.string.btn_unlock), (DialogInterface.OnClickListener) null);
|
activity.getString(R.string.btn_proceed), (DialogInterface.OnClickListener) null);
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +476,8 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4) {
|
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4 ||
|
||||||
|
mRequiredInput.mType == RequiredInputType.NUMERIC_9X4_AUTOCRYPT) {
|
||||||
StringBuilder backupCodeInput = new StringBuilder(36);
|
StringBuilder backupCodeInput = new StringBuilder(36);
|
||||||
if (mRequiredInput.hasPassphraseBegin()) {
|
if (mRequiredInput.hasPassphraseBegin()) {
|
||||||
backupCodeInput.append(mRequiredInput.getPassphraseBegin());
|
backupCodeInput.append(mRequiredInput.getPassphraseBegin());
|
||||||
|
|||||||
@@ -163,7 +163,8 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
|
|||||||
case PASSPHRASE:
|
case PASSPHRASE:
|
||||||
case PASSPHRASE_SYMMETRIC:
|
case PASSPHRASE_SYMMETRIC:
|
||||||
case BACKUP_CODE:
|
case BACKUP_CODE:
|
||||||
case NUMERIC_9X4: {
|
case NUMERIC_9X4:
|
||||||
|
case NUMERIC_9X4_AUTOCRYPT: {
|
||||||
Intent intent = new Intent(activity, PassphraseDialogActivity.class);
|
Intent intent = new Intent(activity, PassphraseDialogActivity.class);
|
||||||
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
|
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
|
||||||
intent.putExtra(PassphraseDialogActivity.EXTRA_CRYPTO_INPUT, cryptoInputParcel);
|
intent.putExtra(PassphraseDialogActivity.EXTRA_CRYPTO_INPUT, cryptoInputParcel);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="24dp"
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:text="@string/passphrase_transfer"
|
android:text="@string/passphrase_transfer"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
<string name="btn_encrypt_text">"Encrypt text"</string>
|
<string name="btn_encrypt_text">"Encrypt text"</string>
|
||||||
<string name="btn_add_email">"Add additional email address"</string>
|
<string name="btn_add_email">"Add additional email address"</string>
|
||||||
<string name="btn_unlock">"Unlock"</string>
|
<string name="btn_unlock">"Unlock"</string>
|
||||||
|
<string name="btn_proceed">"Proceed"</string>
|
||||||
<string name="btn_add_keyserver">"Add"</string>
|
<string name="btn_add_keyserver">"Add"</string>
|
||||||
<string name="btn_save_default">"Save as default"</string>
|
<string name="btn_save_default">"Save as default"</string>
|
||||||
<string name="btn_saved">"Saved!"</string>
|
<string name="btn_saved">"Saved!"</string>
|
||||||
@@ -334,6 +335,7 @@
|
|||||||
<string name="passphrase_keyboard_hint_alpha">"Switch to alphabetic keyboard"</string>
|
<string name="passphrase_keyboard_hint_alpha">"Switch to alphabetic keyboard"</string>
|
||||||
<string name="passphrase_keyboard_hint_numeric">"Switch to numeric keyboard"</string>
|
<string name="passphrase_keyboard_hint_numeric">"Switch to numeric keyboard"</string>
|
||||||
<string name="passphrase_transfer">"Enter transfer code"</string>
|
<string name="passphrase_transfer">"Enter transfer code"</string>
|
||||||
|
<string name="passphrase_transfer_autocrypt">"To import this Autocrypt Setup Message, enter transfer code:"</string>
|
||||||
<string name="pin_for">"Enter PIN for '%s'"</string>
|
<string name="pin_for">"Enter PIN for '%s'"</string>
|
||||||
<string name="security_token_pin_for">"Enter PIN to access Security Token for '%s'"</string>
|
<string name="security_token_pin_for">"Enter PIN to access Security Token for '%s'"</string>
|
||||||
<string name="security_token_nfc_text">"Hold Security Token against the NFC marker at the back of your device."</string>
|
<string name="security_token_nfc_text">"Hold Security Token against the NFC marker at the back of your device."</string>
|
||||||
@@ -634,6 +636,7 @@
|
|||||||
<string name="intent_import_key">"Import Key with OpenKeychain"</string>
|
<string name="intent_import_key">"Import Key with OpenKeychain"</string>
|
||||||
<string name="intent_send_encrypt">"Encrypt with OpenKeychain"</string>
|
<string name="intent_send_encrypt">"Encrypt with OpenKeychain"</string>
|
||||||
<string name="intent_send_decrypt">"Decrypt with OpenKeychain"</string>
|
<string name="intent_send_decrypt">"Decrypt with OpenKeychain"</string>
|
||||||
|
<string name="intent_autocrypt_setup">"Import Autocrypt Setup Message"</string>
|
||||||
|
|
||||||
<!-- Remote API -->
|
<!-- Remote API -->
|
||||||
<string name="api_settings_show_info">"Show advanced information"</string>
|
<string name="api_settings_show_info">"Show advanced information"</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user