Merge branch 'master' of https://github.com/open-keychain/open-keychain into improve-file
@ -65,7 +65,7 @@
|
||||
android:name=".KeychainApplication"
|
||||
android:allowBackup="false"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@drawable/icon"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:theme="@style/KeychainTheme"
|
||||
android:label="@string/app_name">
|
||||
<activity
|
||||
|
@ -53,15 +53,16 @@ public class KeybaseKeyserver extends Keyserver {
|
||||
|
||||
// only list them if they have a key
|
||||
if (JWalk.optObject(match, "components", "key_fingerprint") != null) {
|
||||
String keybaseId = JWalk.getString(match, "components", "username", "val");
|
||||
String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val");
|
||||
fingerprint = fingerprint.replace(" ", "").toUpperCase();
|
||||
|
||||
if (keybaseId.equals(query) || fingerprint.startsWith(query.toUpperCase())) {
|
||||
// TODO: needed anymore?
|
||||
// String keybaseId = JWalk.getString(match, "components", "username", "val");
|
||||
// String fingerprint = JWalk.getString(match, "components", "key_fingerprint", "val");
|
||||
// fingerprint = fingerprint.replace(" ", "").toUpperCase();
|
||||
// if (keybaseId.equals(query) || fingerprint.startsWith(query.toUpperCase())) {
|
||||
// results.add(makeEntry(match));
|
||||
// } else {
|
||||
// results.add(makeEntry(match));
|
||||
// }
|
||||
results.add(makeEntry(match));
|
||||
} else {
|
||||
results.add(makeEntry(match));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -35,7 +35,6 @@ public class OpenPgpSignatureResultBuilder {
|
||||
private boolean mSignatureAvailable = false;
|
||||
private boolean mKnownKey = false;
|
||||
private boolean mValidSignature = false;
|
||||
private boolean mValidKeyBinding = false;
|
||||
private boolean mIsSignatureKeyCertified = false;
|
||||
|
||||
public void signatureOnly(boolean signatureOnly) {
|
||||
@ -58,10 +57,6 @@ public class OpenPgpSignatureResultBuilder {
|
||||
this.mValidSignature = validSignature;
|
||||
}
|
||||
|
||||
public void validKeyBinding(boolean validKeyBinding) {
|
||||
this.mValidKeyBinding = validKeyBinding;
|
||||
}
|
||||
|
||||
public void signatureKeyCertified(boolean isSignatureKeyCertified) {
|
||||
this.mIsSignatureKeyCertified = isSignatureKeyCertified;
|
||||
}
|
||||
@ -77,7 +72,7 @@ public class OpenPgpSignatureResultBuilder {
|
||||
|
||||
// valid sig!
|
||||
if (mKnownKey) {
|
||||
if (mValidKeyBinding && mValidSignature) {
|
||||
if (mValidSignature) {
|
||||
result.setKeyId(mKeyId);
|
||||
result.setUserId(mUserId);
|
||||
|
||||
@ -89,8 +84,7 @@ public class OpenPgpSignatureResultBuilder {
|
||||
result.setStatus(OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED);
|
||||
}
|
||||
} else {
|
||||
Log.d(Constants.TAG, "Error!\nvalidKeyBinding: " + mValidKeyBinding
|
||||
+ "\nvalidSignature: " + mValidSignature);
|
||||
Log.d(Constants.TAG, "Error! Invalid signature.");
|
||||
result.setStatus(OpenPgpSignatureResult.SIGNATURE_ERROR);
|
||||
}
|
||||
} else {
|
||||
|
@ -122,9 +122,6 @@ public class PgpDecryptVerify {
|
||||
/**
|
||||
* Allow these key ids alone for decryption.
|
||||
* This means only ciphertexts encrypted for one of these private key can be decrypted.
|
||||
*
|
||||
* @param allowedKeyIds
|
||||
* @return
|
||||
*/
|
||||
public Builder setAllowedKeyIds(Set<Long> allowedKeyIds) {
|
||||
this.mAllowedKeyIds = allowedKeyIds;
|
||||
@ -496,10 +493,7 @@ public class PgpDecryptVerify {
|
||||
|
||||
// Verify signature and check binding signatures
|
||||
boolean validSignature = signature.verify(messageSignature);
|
||||
boolean validKeyBinding = signingRing.verifySubkeyBinding(signingKey);
|
||||
|
||||
signatureResultBuilder.validSignature(validSignature);
|
||||
signatureResultBuilder.validKeyBinding(validKeyBinding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,10 +637,8 @@ public class PgpDecryptVerify {
|
||||
|
||||
// Verify signature and check binding signatures
|
||||
boolean validSignature = signature.verify();
|
||||
boolean validKeyBinding = signingRing.verifySubkeyBinding(signingKey);
|
||||
|
||||
signatureResultBuilder.validSignature(validSignature);
|
||||
signatureResultBuilder.validKeyBinding(validKeyBinding);
|
||||
}
|
||||
|
||||
result.setSignatureResult(signatureResultBuilder.build());
|
||||
@ -657,10 +649,6 @@ public class PgpDecryptVerify {
|
||||
|
||||
/**
|
||||
* Mostly taken from ClearSignedFileProcessor in Bouncy Castle
|
||||
*
|
||||
* @param sig
|
||||
* @param line
|
||||
* @throws SignatureException
|
||||
*/
|
||||
private static void processLine(PGPSignature sig, byte[] line)
|
||||
throws SignatureException {
|
||||
|
@ -60,7 +60,7 @@ public class PgpHelper {
|
||||
}
|
||||
|
||||
public static String getFullVersion(Context context) {
|
||||
return "OpenPGP Keychain v" + getVersion(context);
|
||||
return "OpenKeychain v" + getVersion(context);
|
||||
}
|
||||
|
||||
// public static final class content {
|
||||
|
@ -226,7 +226,7 @@ public class PgpImportExport {
|
||||
|
||||
try {
|
||||
WrappedPublicKeyRing ring = mProviderHelper.getWrappedPublicKeyRing(
|
||||
KeychainContract.KeyRings.buildGenericKeyRingUri(pubKeyMasterId)
|
||||
KeychainContract.KeyRings.buildUnifiedKeyRingUri(pubKeyMasterId)
|
||||
);
|
||||
|
||||
ring.encode(arOutStream);
|
||||
|
@ -547,6 +547,7 @@ public class UncachedKeyRing {
|
||||
|
||||
// if we already have a cert, and this one is not newer: skip it
|
||||
if (selfCert != null && selfCert.getCreationTime().before(cert.getCreationTime())) {
|
||||
log.add(LogLevel.DEBUG, LogType.MSG_KC_SUB_DUP, indent);
|
||||
redundantCerts += 1;
|
||||
continue;
|
||||
}
|
||||
@ -574,8 +575,9 @@ public class UncachedKeyRing {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if there is no binding (yet), or the revocation is newer than the binding: keep it
|
||||
// if there is a certification that is newer than this revocation, don't bother
|
||||
if (selfCert != null && selfCert.getCreationTime().after(cert.getCreationTime())) {
|
||||
log.add(LogLevel.DEBUG, LogType.MSG_KC_SUB_REVOKE_DUP, indent);
|
||||
redundantCerts += 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -1,24 +1,16 @@
|
||||
package org.sufficientlysecure.keychain.pgp;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.SignatureSubpacketTags;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyRing;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class WrappedPublicKeyRing extends WrappedKeyRing {
|
||||
@ -70,106 +62,11 @@ public class WrappedPublicKeyRing extends WrappedKeyRing {
|
||||
}
|
||||
return cKey;
|
||||
}
|
||||
// TODO handle with proper exception
|
||||
throw new PgpGeneralException("no encryption key available");
|
||||
}
|
||||
|
||||
public boolean verifySubkeyBinding(WrappedPublicKey cachedSubkey) {
|
||||
boolean validSubkeyBinding = false;
|
||||
boolean validTempSubkeyBinding = false;
|
||||
boolean validPrimaryKeyBinding = false;
|
||||
|
||||
PGPPublicKey masterKey = getRing().getPublicKey();
|
||||
PGPPublicKey subKey = cachedSubkey.getPublicKey();
|
||||
|
||||
// Is this the master key? Match automatically, then.
|
||||
if(Arrays.equals(masterKey.getFingerprint(), subKey.getFingerprint())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
||||
new JcaPGPContentVerifierBuilderProvider()
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
|
||||
Iterator<PGPSignature> itr = subKey.getSignatures();
|
||||
|
||||
while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong?
|
||||
//gpg has an invalid subkey binding error on key import I think, but doesn't shout
|
||||
//about keys without subkey signing. Can't get it to import a slightly broken one
|
||||
//either, so we will err on bad subkey binding here.
|
||||
PGPSignature sig = itr.next();
|
||||
if (sig.getKeyID() == masterKey.getKeyID() &&
|
||||
sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) {
|
||||
//check and if ok, check primary key binding.
|
||||
try {
|
||||
sig.init(contentVerifierBuilderProvider, masterKey);
|
||||
validTempSubkeyBinding = sig.verifyCertification(masterKey, subKey);
|
||||
} catch (PGPException e) {
|
||||
continue;
|
||||
} catch (SignatureException e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (validTempSubkeyBinding) {
|
||||
validSubkeyBinding = true;
|
||||
}
|
||||
if (validTempSubkeyBinding) {
|
||||
validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getUnhashedSubPackets(),
|
||||
masterKey, subKey);
|
||||
if (validPrimaryKeyBinding) {
|
||||
break;
|
||||
}
|
||||
validPrimaryKeyBinding = verifyPrimaryKeyBinding(sig.getHashedSubPackets(),
|
||||
masterKey, subKey);
|
||||
if (validPrimaryKeyBinding) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return validSubkeyBinding && validPrimaryKeyBinding;
|
||||
|
||||
}
|
||||
|
||||
static boolean verifyPrimaryKeyBinding(PGPSignatureSubpacketVector pkts,
|
||||
PGPPublicKey masterPublicKey,
|
||||
PGPPublicKey signingPublicKey) {
|
||||
boolean validPrimaryKeyBinding = false;
|
||||
JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider =
|
||||
new JcaPGPContentVerifierBuilderProvider()
|
||||
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME);
|
||||
PGPSignatureList eSigList;
|
||||
|
||||
if (pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) {
|
||||
try {
|
||||
eSigList = pkts.getEmbeddedSignatures();
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} catch (PGPException e) {
|
||||
return false;
|
||||
}
|
||||
for (int j = 0; j < eSigList.size(); ++j) {
|
||||
PGPSignature emSig = eSigList.get(j);
|
||||
if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) {
|
||||
try {
|
||||
emSig.init(contentVerifierBuilderProvider, signingPublicKey);
|
||||
validPrimaryKeyBinding = emSig.verifyCertification(masterPublicKey, signingPublicKey);
|
||||
if (validPrimaryKeyBinding) {
|
||||
break;
|
||||
}
|
||||
} catch (PGPException e) {
|
||||
continue;
|
||||
} catch (SignatureException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validPrimaryKeyBinding;
|
||||
}
|
||||
|
||||
public IterableIterator<WrappedPublicKey> publicKeyIterator() {
|
||||
@SuppressWarnings("unchecked")
|
||||
final Iterator<PGPPublicKey> it = getRing().getPublicKeys();
|
||||
return new IterableIterator<WrappedPublicKey>(new Iterator<WrappedPublicKey>() {
|
||||
@Override
|
||||
|
@ -201,6 +201,7 @@ public class OperationResultParcel implements Parcelable {
|
||||
MSG_KC_SUB_BAD_KEYID(R.string.msg_kc_sub_bad_keyid),
|
||||
MSG_KC_SUB_BAD_TIME(R.string.msg_kc_sub_bad_time),
|
||||
MSG_KC_SUB_BAD_TYPE(R.string.msg_kc_sub_bad_type),
|
||||
MSG_KC_SUB_DUP (R.string.msg_kc_sub_dup),
|
||||
MSG_KC_SUB_PRIMARY_BAD(R.string.msg_kc_sub_primary_bad),
|
||||
MSG_KC_SUB_PRIMARY_BAD_ERR(R.string.msg_kc_sub_primary_bad_err),
|
||||
MSG_KC_SUB_PRIMARY_NONE(R.string.msg_kc_sub_primary_none),
|
||||
|
@ -18,9 +18,7 @@
|
||||
package org.sufficientlysecure.keychain.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.nfc.NdefMessage;
|
||||
@ -31,16 +29,12 @@ import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import com.github.johnpersano.supertoasts.SuperCardToast;
|
||||
import com.github.johnpersano.supertoasts.SuperToast;
|
||||
@ -51,7 +45,6 @@ import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
|
||||
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
@ -130,60 +123,13 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
|
||||
mNavigationStrings = getResources().getStringArray(R.array.import_action_list);
|
||||
|
||||
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
|
||||
setTitle(R.string.nav_import);
|
||||
} else {
|
||||
initTabs();
|
||||
}
|
||||
// TODO: add actionbar button for this action?
|
||||
// if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
|
||||
// }
|
||||
|
||||
handleActions(savedInstanceState, getIntent());
|
||||
}
|
||||
|
||||
private void initTabs() {
|
||||
mTabsAdapter = new PagerTabStripAdapter(this);
|
||||
mViewPager.setAdapter(mTabsAdapter);
|
||||
mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
// resize view pager back to 64 if keyserver settings have been collapsed
|
||||
if (getViewPagerHeight() > VIEW_PAGER_HEIGHT) {
|
||||
resizeViewPager(VIEW_PAGER_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
|
||||
Bundle serverBundle = new Bundle();
|
||||
// serverBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
|
||||
mTabsAdapter.addTab(ImportKeysServerFragment.class,
|
||||
serverBundle, getString(R.string.import_tab_keyserver));
|
||||
|
||||
Bundle qrCodeBundle = new Bundle();
|
||||
// importBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
|
||||
mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
|
||||
qrCodeBundle, getString(R.string.import_tab_qr_code));
|
||||
|
||||
Bundle fileBundle = new Bundle();
|
||||
// importBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
|
||||
mTabsAdapter.addTab(ImportKeysFileFragment.class,
|
||||
fileBundle, getString(R.string.import_tab_direct));
|
||||
|
||||
Bundle keybaseBundle = new Bundle();
|
||||
// keybaseBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
|
||||
mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
|
||||
keybaseBundle, getString(R.string.import_tab_keybase));
|
||||
|
||||
// update layout after operations
|
||||
mSlidingTabLayout.setViewPager(mViewPager);
|
||||
}
|
||||
|
||||
protected void handleActions(Bundle savedInstanceState, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Bundle extras = intent.getExtras();
|
||||
@ -200,6 +146,8 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
action = ACTION_IMPORT_KEY;
|
||||
}
|
||||
|
||||
Bundle serverBundle = null;
|
||||
boolean serverOnly = false;
|
||||
if (scheme != null && scheme.toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) {
|
||||
/* Scanning a fingerprint directly with Barcode Scanner */
|
||||
loadFromFingerprintUri(savedInstanceState, dataUri);
|
||||
@ -240,10 +188,8 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
|
||||
if (query != null && query.length() > 0) {
|
||||
// display keyserver fragment with query
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||
// loadNavFragment(NAV_SERVER, args);
|
||||
//TODO: load afterwards!
|
||||
serverBundle = new Bundle();
|
||||
serverBundle.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||
mSwitchToTab = NAV_SERVER;
|
||||
|
||||
// action: search immediately
|
||||
@ -259,7 +205,19 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
*/
|
||||
|
||||
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
|
||||
loadFromFingerprint(savedInstanceState, fingerprint);
|
||||
if (isFingerprintValid(fingerprint)) {
|
||||
String query = "0x" + fingerprint;
|
||||
|
||||
// display keyserver fragment with query
|
||||
serverBundle = new Bundle();
|
||||
serverBundle.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||
serverBundle.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
|
||||
serverOnly = true;
|
||||
mSwitchToTab = NAV_SERVER;
|
||||
|
||||
// action: search immediately
|
||||
startListFragment(savedInstanceState, null, null, query);
|
||||
}
|
||||
} else {
|
||||
Log.e(Constants.TAG,
|
||||
"IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or " +
|
||||
@ -298,6 +256,44 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
startListFragment(savedInstanceState, null, null, null);
|
||||
}
|
||||
|
||||
initTabs(serverBundle, serverOnly);
|
||||
}
|
||||
|
||||
private void initTabs(Bundle serverBundle, boolean serverOnly) {
|
||||
mTabsAdapter = new PagerTabStripAdapter(this);
|
||||
mViewPager.setAdapter(mTabsAdapter);
|
||||
mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
// resize view pager back to 64 if keyserver settings have been collapsed
|
||||
if (getViewPagerHeight() > VIEW_PAGER_HEIGHT) {
|
||||
resizeViewPager(VIEW_PAGER_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
}
|
||||
});
|
||||
|
||||
mTabsAdapter.addTab(ImportKeysServerFragment.class,
|
||||
serverBundle, getString(R.string.import_tab_keyserver));
|
||||
if (!serverOnly) {
|
||||
mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
|
||||
null, getString(R.string.import_tab_qr_code));
|
||||
mTabsAdapter.addTab(ImportKeysFileFragment.class,
|
||||
null, getString(R.string.import_tab_direct));
|
||||
mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
|
||||
null, getString(R.string.import_tab_keybase));
|
||||
}
|
||||
|
||||
// update layout after operations
|
||||
mSlidingTabLayout.setViewPager(mViewPager);
|
||||
|
||||
mViewPager.setCurrentItem(mSwitchToTab);
|
||||
}
|
||||
|
||||
@ -338,35 +334,52 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
|
||||
Log.d(Constants.TAG, "fingerprint: " + fingerprint);
|
||||
|
||||
loadFromFingerprint(savedInstanceState, fingerprint);
|
||||
// TODO: reload fragment when coming from qr code!
|
||||
// loadFromFingerprint(savedInstanceState, fingerprint);
|
||||
|
||||
|
||||
// String query = "0x" + fingerprint;
|
||||
//
|
||||
// // display keyserver fragment with query
|
||||
// Bundle serverBundle = new Bundle();
|
||||
// serverBundle.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||
// serverBundle.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
|
||||
//
|
||||
// return serverBundle;
|
||||
}
|
||||
|
||||
public void loadFromFingerprint(Bundle savedInstanceState, String fingerprint) {
|
||||
private boolean isFingerprintValid(String fingerprint) {
|
||||
if (fingerprint == null || fingerprint.length() < 40) {
|
||||
SuperCardToast toast = SuperCardToast.create(this,
|
||||
getString(R.string.import_qr_code_too_short_fingerprint),
|
||||
SuperToast.Duration.LONG);
|
||||
toast.setBackground(SuperToast.Background.RED);
|
||||
toast.show();
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String query = "0x" + fingerprint;
|
||||
/**
|
||||
* Scroll ViewPager left and right
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
boolean result = super.onTouchEvent(event);
|
||||
|
||||
// display keyserver fragment with query
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
|
||||
args.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
|
||||
// loadNavFragment(NAV_SERVER, args);
|
||||
|
||||
//TODO
|
||||
|
||||
// action: search directly
|
||||
startListFragment(savedInstanceState, null, null, query);
|
||||
if (!result) {
|
||||
mViewPager.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void loadCallback(byte[] importData, Uri dataUri, String serverQuery, String keyServer, String keybaseQuery) {
|
||||
mListFragment.loadNew(importData, dataUri, serverQuery, keyServer, keybaseQuery);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void loadCallback(ImportKeysListFragment.LoaderState loaderState) {
|
||||
mListFragment.loadNew(loaderState);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -477,7 +490,8 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
}
|
||||
};
|
||||
|
||||
if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
|
||||
ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState();
|
||||
if (ls instanceof ImportKeysListFragment.BytesLoaderState) {
|
||||
Log.d(Constants.TAG, "importKeys started");
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
@ -503,7 +517,9 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
|
||||
// start service with intent
|
||||
startService(intent);
|
||||
} else if (mListFragment.getServerQuery() != null) {
|
||||
} else if (ls instanceof ImportKeysListFragment.KeyserverLoaderState) {
|
||||
ImportKeysListFragment.KeyserverLoaderState sls = (ImportKeysListFragment.KeyserverLoaderState) ls;
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
|
||||
@ -512,7 +528,7 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
data.putString(KeychainIntentService.DOWNLOAD_KEY_SERVER, mListFragment.getKeyServer());
|
||||
data.putString(KeychainIntentService.DOWNLOAD_KEY_SERVER, sls.keyserver);
|
||||
|
||||
// get selected key entries
|
||||
ArrayList<ImportKeysListEntry> selectedEntries = mListFragment.getSelectedEntries();
|
||||
@ -529,7 +545,7 @@ public class ImportKeysActivity extends ActionBarActivity {
|
||||
|
||||
// start service with intent
|
||||
startService(intent);
|
||||
} else if (mListFragment.getKeybaseQuery() != null) {
|
||||
} else if (ls instanceof ImportKeysListFragment.KeybaseLoaderState) {
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class ImportKeysFileFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mImportActivity.loadCallback(sendText.getBytes(), null, null, null, null);
|
||||
mImportActivity.loadCallback(new ImportKeysListFragment.BytesLoaderState(sendText.getBytes(), null));
|
||||
}
|
||||
});
|
||||
|
||||
@ -107,7 +107,7 @@ public class ImportKeysFileFragment extends Fragment {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
|
||||
// load data
|
||||
mImportActivity.loadCallback(null, data.getData(), null, null, null);
|
||||
mImportActivity.loadCallback(new ImportKeysListFragment.BytesLoaderState(null, data.getData()));
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -117,6 +117,6 @@ public class ImportKeysKeybaseFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void search(String query) {
|
||||
mImportActivity.loadCallback(null, null, null, null, query);
|
||||
mImportActivity.loadCallback(new ImportKeysListFragment.KeybaseLoaderState(query));
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ import android.support.v4.util.LongSparseArray;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.devspark.appmsg.AppMsg;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.helper.Preferences;
|
||||
@ -60,11 +58,7 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
private Activity mActivity;
|
||||
private ImportKeysAdapter mAdapter;
|
||||
|
||||
private byte[] mKeyBytes;
|
||||
private Uri mDataUri;
|
||||
private String mServerQuery;
|
||||
private String mKeyServer;
|
||||
private String mKeybaseQuery;
|
||||
private LoaderState mLoaderState;
|
||||
|
||||
private static final int LOADER_ID_BYTES = 0;
|
||||
private static final int LOADER_ID_SERVER_QUERY = 1;
|
||||
@ -72,24 +66,8 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
|
||||
private LongSparseArray<ParcelableKeyRing> mCachedKeyData;
|
||||
|
||||
public byte[] getKeyBytes() {
|
||||
return mKeyBytes;
|
||||
}
|
||||
|
||||
public Uri getDataUri() {
|
||||
return mDataUri;
|
||||
}
|
||||
|
||||
public String getServerQuery() {
|
||||
return mServerQuery;
|
||||
}
|
||||
|
||||
public String getKeybaseQuery() {
|
||||
return mKeybaseQuery;
|
||||
}
|
||||
|
||||
public String getKeyServer() {
|
||||
return mKeyServer;
|
||||
public LoaderState getLoaderState() {
|
||||
return mLoaderState;
|
||||
}
|
||||
|
||||
public List<ImportKeysListEntry> getData() {
|
||||
@ -124,6 +102,37 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
return frag;
|
||||
}
|
||||
|
||||
static public class LoaderState {
|
||||
}
|
||||
|
||||
static public class BytesLoaderState extends LoaderState {
|
||||
byte[] keyBytes;
|
||||
Uri dataUri;
|
||||
|
||||
BytesLoaderState(byte[] keyBytes, Uri dataUri) {
|
||||
this.keyBytes = keyBytes;
|
||||
this.dataUri = dataUri;
|
||||
}
|
||||
}
|
||||
|
||||
static public class KeyserverLoaderState extends LoaderState {
|
||||
String serverQuery;
|
||||
String keyserver;
|
||||
|
||||
KeyserverLoaderState(String serverQuery, String keyserver) {
|
||||
this.serverQuery = serverQuery;
|
||||
this.keyserver = keyserver;
|
||||
}
|
||||
}
|
||||
|
||||
static public class KeybaseLoaderState extends LoaderState {
|
||||
String keybaseQuery;
|
||||
|
||||
KeybaseLoaderState(String keybaseQuery) {
|
||||
this.keybaseQuery = keybaseQuery;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Adapter and Loader on create of Activity
|
||||
*/
|
||||
@ -140,43 +149,20 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
mAdapter = new ImportKeysAdapter(mActivity);
|
||||
setListAdapter(mAdapter);
|
||||
|
||||
mDataUri = getArguments().getParcelable(ARG_DATA_URI);
|
||||
mKeyBytes = getArguments().getByteArray(ARG_BYTES);
|
||||
mServerQuery = getArguments().getString(ARG_SERVER_QUERY);
|
||||
|
||||
// TODO: this is used when scanning QR Code. Currently it simply uses keyserver nr 0
|
||||
mKeyServer = Preferences.getPreferences(getActivity())
|
||||
if (getArguments().containsKey(ARG_DATA_URI) || getArguments().containsKey(ARG_BYTES)) {
|
||||
Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
|
||||
byte[] bytes = getArguments().getByteArray(ARG_BYTES);
|
||||
mLoaderState = new BytesLoaderState(bytes, dataUri);
|
||||
} else if (getArguments().containsKey(ARG_SERVER_QUERY)) {
|
||||
String query = getArguments().getString(ARG_SERVER_QUERY);
|
||||
// TODO: this is used when scanning QR Code or updating a key.
|
||||
// Currently it simply uses keyserver nr 0
|
||||
String keyserver = Preferences.getPreferences(getActivity())
|
||||
.getKeyServers()[0];
|
||||
|
||||
if (mDataUri != null || mKeyBytes != null) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
// Prepare the loader. Either re-connect with an existing one,
|
||||
// or start a new one.
|
||||
// give arguments to onCreateLoader()
|
||||
getLoaderManager().initLoader(LOADER_ID_BYTES, null, this);
|
||||
mLoaderState = new KeyserverLoaderState(query, keyserver);
|
||||
}
|
||||
|
||||
if (mServerQuery != null && mKeyServer != null) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
// Prepare the loader. Either re-connect with an existing one,
|
||||
// or start a new one.
|
||||
// give arguments to onCreateLoader()
|
||||
getLoaderManager().initLoader(LOADER_ID_SERVER_QUERY, null, this);
|
||||
}
|
||||
|
||||
if (mKeybaseQuery != null) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
// Prepare the loader. Either re-connect with an existing one,
|
||||
// or start a new one.
|
||||
// give arguments to onCreateLoader()
|
||||
getLoaderManager().initLoader(LOADER_ID_KEYBASE, null, this);
|
||||
}
|
||||
restartLoaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -192,31 +178,33 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void loadNew(byte[] keyBytes, Uri dataUri, String serverQuery, String keyServer, String keybaseQuery) {
|
||||
mKeyBytes = keyBytes;
|
||||
mDataUri = dataUri;
|
||||
mServerQuery = serverQuery;
|
||||
mKeyServer = keyServer;
|
||||
mKeybaseQuery = keybaseQuery;
|
||||
public void loadNew(LoaderState loaderState) {
|
||||
mLoaderState = loaderState;
|
||||
|
||||
if (mKeyBytes != null || mDataUri != null) {
|
||||
restartLoaders();
|
||||
}
|
||||
|
||||
private void restartLoaders() {
|
||||
if (mLoaderState instanceof BytesLoaderState) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this);
|
||||
}
|
||||
|
||||
if (mServerQuery != null && mKeyServer != null) {
|
||||
getLoaderManager().destroyLoader(LOADER_ID_SERVER_QUERY);
|
||||
getLoaderManager().destroyLoader(LOADER_ID_KEYBASE);
|
||||
} else if (mLoaderState instanceof KeyserverLoaderState) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
getLoaderManager().destroyLoader(LOADER_ID_BYTES);
|
||||
getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this);
|
||||
}
|
||||
|
||||
if (mKeybaseQuery != null) {
|
||||
getLoaderManager().destroyLoader(LOADER_ID_KEYBASE);
|
||||
} else if (mLoaderState instanceof KeybaseLoaderState) {
|
||||
// Start out with a progress indicator.
|
||||
setListShown(false);
|
||||
|
||||
getLoaderManager().destroyLoader(LOADER_ID_BYTES);
|
||||
getLoaderManager().destroyLoader(LOADER_ID_SERVER_QUERY);
|
||||
getLoaderManager().restartLoader(LOADER_ID_KEYBASE, null, this);
|
||||
}
|
||||
}
|
||||
@ -226,14 +214,17 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
onCreateLoader(int id, Bundle args) {
|
||||
switch (id) {
|
||||
case LOADER_ID_BYTES: {
|
||||
InputData inputData = getInputData(mKeyBytes, mDataUri);
|
||||
BytesLoaderState ls = (BytesLoaderState) mLoaderState;
|
||||
InputData inputData = getInputData(ls.keyBytes, ls.dataUri);
|
||||
return new ImportKeysListLoader(mActivity, inputData);
|
||||
}
|
||||
case LOADER_ID_SERVER_QUERY: {
|
||||
return new ImportKeysListServerLoader(getActivity(), mServerQuery, mKeyServer);
|
||||
KeyserverLoaderState ls = (KeyserverLoaderState) mLoaderState;
|
||||
return new ImportKeysListServerLoader(getActivity(), ls.serverQuery, ls.keyserver);
|
||||
}
|
||||
case LOADER_ID_KEYBASE: {
|
||||
return new ImportKeysListKeybaseLoader(getActivity(), mKeybaseQuery);
|
||||
KeybaseLoaderState ls = (KeybaseLoaderState) mLoaderState;
|
||||
return new ImportKeysListKeybaseLoader(getActivity(), ls.keybaseQuery);
|
||||
}
|
||||
|
||||
default:
|
||||
@ -280,7 +271,8 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
|
||||
getQuantityString(R.plurals.error_import_non_pgp_part,
|
||||
((ImportKeysListLoader.NonPgpPart) error).getCount()),
|
||||
Notify.Style.OK);
|
||||
Notify.Style.OK
|
||||
);
|
||||
} else {
|
||||
Notify.showNotify(getActivity(), R.string.error_generic_report_bug, Notify.Style.ERROR);
|
||||
}
|
||||
@ -289,7 +281,6 @@ public class ImportKeysListFragment extends ListFragment implements
|
||||
case LOADER_ID_SERVER_QUERY:
|
||||
case LOADER_ID_KEYBASE:
|
||||
|
||||
// TODO: possibly fine-tune message building for these two cases
|
||||
if (error == null) {
|
||||
// No error
|
||||
} else if (error instanceof Keyserver.QueryTooShortException) {
|
||||
|
@ -25,8 +25,6 @@ import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
@ -36,18 +34,13 @@ import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Notify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ImportKeysQrCodeFragment extends Fragment {
|
||||
private ImportKeysActivity mImportActivity;
|
||||
|
||||
private View mNfcButton;
|
||||
|
||||
private View mQrCodeButton;
|
||||
private TextView mQrCodeText;
|
||||
private ProgressBar mQrCodeProgress;
|
||||
|
||||
private String[] mQrCodeContent;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
@ -81,8 +74,6 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
||||
});
|
||||
|
||||
mQrCodeButton = view.findViewById(R.id.import_qrcode_button);
|
||||
mQrCodeText = (TextView) view.findViewById(R.id.import_qrcode_text);
|
||||
mQrCodeProgress = (ProgressBar) view.findViewById(R.id.import_qrcode_progress);
|
||||
|
||||
mQrCodeButton.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@ -120,16 +111,9 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
||||
return;
|
||||
}
|
||||
|
||||
// look if it is the whole key
|
||||
String[] parts = scannedContent.split(",");
|
||||
if (parts.length == 3) {
|
||||
importParts(parts);
|
||||
return;
|
||||
}
|
||||
|
||||
// is this a full key encoded as qr code?
|
||||
if (scannedContent.startsWith("-----BEGIN PGP")) {
|
||||
mImportActivity.loadCallback(scannedContent.getBytes(), null, null, null, null);
|
||||
mImportActivity.loadCallback(new ImportKeysListFragment.BytesLoaderState(scannedContent.getBytes(), null));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,68 +131,8 @@ public class ImportKeysQrCodeFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void importFingerprint(Uri dataUri) {
|
||||
mImportActivity.loadFromFingerprintUri(null, dataUri);
|
||||
}
|
||||
|
||||
private void importParts(String[] parts) {
|
||||
int counter = Integer.valueOf(parts[0]);
|
||||
int size = Integer.valueOf(parts[1]);
|
||||
String content = parts[2];
|
||||
|
||||
Log.d(Constants.TAG, "" + counter);
|
||||
Log.d(Constants.TAG, "" + size);
|
||||
Log.d(Constants.TAG, "" + content);
|
||||
|
||||
// first qr code -> setup
|
||||
if (counter == 0) {
|
||||
mQrCodeContent = new String[size];
|
||||
mQrCodeProgress.setMax(size);
|
||||
mQrCodeProgress.setVisibility(View.VISIBLE);
|
||||
mQrCodeText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (mQrCodeContent == null || counter > mQrCodeContent.length) {
|
||||
Notify.showNotify(getActivity(), R.string.import_qr_code_start_with_one, Notify.Style.ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// save scanned content
|
||||
mQrCodeContent[counter] = content;
|
||||
|
||||
// get missing numbers
|
||||
ArrayList<Integer> missing = new ArrayList<Integer>();
|
||||
for (int i = 0; i < mQrCodeContent.length; i++) {
|
||||
if (mQrCodeContent[i] == null) {
|
||||
missing.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
// update progress and text
|
||||
int alreadyScanned = mQrCodeContent.length - missing.size();
|
||||
mQrCodeProgress.setProgress(alreadyScanned);
|
||||
|
||||
String missingString = "";
|
||||
for (int m : missing) {
|
||||
if (!missingString.equals("")) {
|
||||
missingString += ", ";
|
||||
}
|
||||
missingString += String.valueOf(m + 1);
|
||||
}
|
||||
|
||||
String missingText = getResources().getQuantityString(R.plurals.import_qr_code_missing,
|
||||
missing.size(), missingString);
|
||||
mQrCodeText.setText(missingText);
|
||||
|
||||
// finished!
|
||||
if (missing.size() == 0) {
|
||||
mQrCodeText.setText(R.string.import_qr_code_finished);
|
||||
String result = "";
|
||||
for (String in : mQrCodeContent) {
|
||||
result += in;
|
||||
}
|
||||
mImportActivity.loadCallback(result.getBytes(), null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,8 +170,8 @@ public class ImportKeysServerFragment extends Fragment {
|
||||
mImportActivity = (ImportKeysActivity) activity;
|
||||
}
|
||||
|
||||
private void search(String query, String keyServer) {
|
||||
mImportActivity.loadCallback(null, null, query, keyServer, null);
|
||||
private void search(String query, String keyserver) {
|
||||
mImportActivity.loadCallback(new ImportKeysListFragment.KeyserverLoaderState(query, keyserver));
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
OpenKeychain/src/main/res/drawable-hdpi/ic_action_nfc.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
OpenKeychain/src/main/res/drawable-mdpi/ic_action_nfc.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
OpenKeychain/src/main/res/drawable-xhdpi/ic_action_nfc.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
BIN
OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_nfc.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -22,7 +22,7 @@
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginRight="6dp"
|
||||
android:src="@drawable/icon" />
|
||||
android:src="@drawable/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/api_app_settings_app_name"
|
||||
|
@ -11,7 +11,7 @@
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/icon" />
|
||||
android:src="@drawable/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/api_apps_adapter_item_name"
|
||||
|
@ -28,7 +28,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginRight="10dp"
|
||||
android:src="@drawable/icon" />
|
||||
android:src="@drawable/ic_launcher" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -18,22 +18,13 @@
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
android:minLines="1"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<View
|
||||
android:layout_width="1dip"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="right"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/import_keybase_search"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_action_search"
|
||||
android:layout_gravity="center_vertical"
|
||||
style="@style/SelectableItem" />
|
||||
|
@ -33,34 +33,15 @@
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<Button
|
||||
<ImageButton
|
||||
android:id="@+id/import_nfc_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="8dp"
|
||||
android:text="NFC?"
|
||||
android:src="@drawable/ic_action_nfc"
|
||||
android:layout_gravity="center_vertical"
|
||||
style="@style/SelectableItem" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/import_qrcode_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/import_qrcode_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:progress="0"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
@ -23,22 +23,13 @@
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
android:minLines="1"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_gravity="center_vertical" />
|
||||
|
||||
<View
|
||||
android:layout_width="1dip"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="right"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/import_server_search"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_action_search"
|
||||
android:layout_gravity="center_vertical"
|
||||
style="@style/SelectableItem" />
|
||||
|
@ -578,13 +578,14 @@
|
||||
<string name="msg_kc_sub_bad_keyid">Subkey binding issuer id mismatch</string>
|
||||
<string name="msg_kc_sub_bad_time">Removing subkey binding certificate with future timestamp</string>
|
||||
<string name="msg_kc_sub_bad_type">Unknown subkey certificate type: %s</string>
|
||||
<string name="msg_kc_sub_dup">Removing redundant subkey binding certificate</string>
|
||||
<string name="msg_kc_sub_primary_bad">Removing subkey binding certificate due to invalid primary binding certificate</string>
|
||||
<string name="msg_kc_sub_primary_bad_err">Removing subkey binding certificate due to bad primary binding certificate</string>
|
||||
<string name="msg_kc_sub_primary_none">Removing subkey binding certificate due to missing primary binding certificate</string>
|
||||
<string name="msg_kc_sub_no_cert">No valid certificate found for %s, removing from ring</string>
|
||||
<string name="msg_kc_sub_revoke_bad_err">Removing bad subkey revocation key</string>
|
||||
<string name="msg_kc_sub_revoke_bad">Removing bad subkey revocation key</string>
|
||||
<string name="msg_kc_sub_revoke_dup">Removing redundant keyring revocation key</string>
|
||||
<string name="msg_kc_sub_revoke_bad_err">Removing bad subkey revocation certificate</string>
|
||||
<string name="msg_kc_sub_revoke_bad">Removing bad subkey revocation certificate</string>
|
||||
<string name="msg_kc_sub_revoke_dup">Removing redundant subkey revocation certificate</string>
|
||||
<string name="msg_kc_success">Keyring canonicalization successful, no changes</string>
|
||||
<string name="msg_kc_success_bad">Keyring canonicalization successful, removed %s erroneous certificates</string>
|
||||
<string name="msg_kc_success_bad_and_red">Keyring canonicalization successful, removed %1$s erroneous and %2$s redundant certificates</string>
|
||||
|
@ -2,5 +2,5 @@
|
||||
|
||||
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:accountType="org.sufficientlysecure.keychain"
|
||||
android:icon="@drawable/icon"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"/>
|
||||
|
61
Resources/graphics/ic_action_nfc.svg
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="ic_action_nfc.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9195959"
|
||||
inkscape:cx="55.015233"
|
||||
inkscape:cy="28.459126"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1179"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="19"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1020.3622)">
|
||||
<path
|
||||
style="fill:#333333;fill-opacity:1;opacity:0.6"
|
||||
d="m 5.8721355,1048.2554 c -0.4529966,-0.1375 -0.740227,-0.4023 -0.9002787,-0.8301 -0.1191051,-0.3184 -0.1207083,-0.4654 -0.1210019,-11.0625 -2.937e-4,-10.087 0.00614,-10.7582 0.1054687,-11.0385 0.1209465,-0.3414 0.3739125,-0.6212 0.714231,-0.7901 0.2298623,-0.1143 0.4666295,-0.1167 10.3597324,-0.1167 9.762967,0 10.132027,0 10.33542,0.1119 0.293646,0.1565 0.533124,0.3907 0.668434,0.6537 0.11192,0.2176 0.115013,0.517 0.115013,11.171 l 0,10.9473 -0.158878,0.292 c -0.170555,0.3133 -0.479601,0.5651 -0.810206,0.6599 -0.246895,0.071 -20.0747083,0.072 -20.3079261,0 z m 16.2976125,-2.4107 c 0.23156,-0.072 0.233209,-0.075 0.197176,-0.3243 -0.01999,-0.1382 -0.06539,-0.3531 -0.100895,-0.4778 -0.05999,-0.2104 -0.07395,-0.2212 -0.197176,-0.1528 -0.08059,0.045 -0.380826,0.075 -0.765398,0.075 -0.599986,0 -0.648397,-0.012 -0.934105,-0.1829 -0.791251,-0.4824 -0.931603,-1.6091 -0.289037,-2.3203 0.358193,-0.3965 0.834326,-0.478 2.00208,-0.3427 0.130096,0.016 0.159263,-0.024 0.265386,-0.3525 0.06557,-0.203 0.10323,-0.411 0.08367,-0.4619 -0.09945,-0.2592 -1.822581,-0.2986 -2.442687,-0.055 -0.730348,0.2858 -1.380503,1.0115 -1.523992,1.7009 -0.163151,0.7839 0.03489,1.6739 0.487021,2.1889 0.242512,0.2762 0.819987,0.6217 1.231169,0.7366 0.365786,0.1023 1.625695,0.083 1.986785,-0.03 z m -11.484429,-1.5922 -0.01861,-1.6494 0.305471,0.5797 c 0.168009,0.3188 0.590546,1.0543 0.938971,1.6343 l 0.633498,1.0547 0.627916,0 0.627916,0 0.01577,-2.3655 0.01577,-2.3653 -0.579954,0 -0.579953,0 0.02229,1.4971 0.02229,1.497 -0.393102,-0.7287 c -0.216208,-0.4008 -0.449401,-0.81 -0.518211,-0.9095 -0.137702,-0.199 -0.444752,-0.7018 -0.671555,-1.0998 l -0.145965,-0.2561 -0.718026,0 -0.7180255,0 0,2.3805 0,2.3804 0.5760585,0 0.576058,0 -0.01861,-1.6494 z m 5.254566,0.7169 0,-0.9325 0.888907,-0.017 0.888907,-0.017 0.0176,-0.467 0.01761,-0.4671 -0.906507,0 -0.906509,0 0,-0.4806 0,-0.4806 0.949172,-0.017 0.949173,-0.017 0.0176,-0.467 0.01761,-0.4671 -1.569422,0 -1.569421,0 0,2.3806 0,2.3804 0.602649,0 0.602648,0 0,-0.9326 z m 6.273699,-6.4951 c 0.263993,-0.1748 0.61016,-0.8748 0.983357,-1.9885 0.326831,-0.9753 0.423664,-1.4032 0.58101,-2.5681 0.146707,-1.0861 0.146304,-1.9076 -0.0016,-3.0218 -0.154191,-1.1622 -0.252803,-1.6038 -0.569457,-2.5496 -0.370747,-1.1074 -0.703918,-1.8019 -0.957103,-1.995 -0.398108,-0.3037 -1.035569,-0.1671 -1.308366,0.2804 -0.1709,0.2803 -0.152866,0.4134 0.144075,1.0638 0.748762,1.6401 1.136923,3.7484 0.996979,5.4153 -0.126969,1.5121 -0.448209,2.7968 -1.003437,4.0129 -0.286491,0.6275 -0.3029,0.8042 -0.103013,1.1092 0.247511,0.3778 0.853068,0.4959 1.237432,0.2414 z m -3.212265,-1.1548 c 0.08951,-0.047 0.234524,-0.162 0.322265,-0.2561 0.350427,-0.3759 0.948601,-2.1223 1.142298,-3.335 0.09437,-0.5908 0.09141,-2.0711 -0.0054,-2.6818 -0.199949,-1.2618 -0.839385,-3.0751 -1.195876,-3.3914 -0.324129,-0.2875 -0.671846,-0.3307 -1.031906,-0.1284 -0.496876,0.2792 -0.547131,0.6948 -0.179059,1.4805 0.135063,0.2883 0.343972,0.8922 0.464242,1.342 0.21768,0.8142 0.218674,0.8235 0.218674,2.0533 0,1.2298 -9.28e-4,1.2392 -0.218674,2.0533 -0.120272,0.4497 -0.325465,1.0465 -0.45599,1.3258 -0.315221,0.6747 -0.334073,0.7469 -0.256435,0.9821 0.160477,0.4864 0.778774,0.7737 1.195836,0.5557 z m -3.174159,-1.6681 c 0.186492,-0.1329 0.54841,-0.7896 0.691807,-1.2555 0.508888,-1.6532 0.377076,-3.2602 -0.388485,-4.7361 -0.327298,-0.6311 -0.615499,-0.8731 -1.039587,-0.8731 -0.674978,0 -0.899355,0.6963 -0.495246,1.5367 0.24473,0.5091 0.384292,1.1084 0.42106,1.808 0.03924,0.7467 -0.04997,1.3559 -0.198551,1.3559 -0.07304,0 -2.190719,-1.4926 -4.081753,-2.877 -1.1019127,-0.8066 -1.3287251,-0.9434 -1.5671351,-0.9452 -0.4533423,0 -0.7275993,0.4736 -0.9154451,1.5925 -0.1551399,0.924 -0.097393,1.9682 0.1566469,2.8324 0.1502703,0.5113 0.2975533,0.7419 0.6027144,0.9438 0.2927514,0.1937 0.5593056,0.2103 0.8029728,0.051 0.3564331,-0.2345 0.4157281,-0.6689 0.2187151,-1.6023 -0.1185758,-0.5619 -0.1563702,-1.0842 -0.083696,-1.1568 0.048046,-0.048 0.316088,0.09 0.775803,0.3986 0.396405,0.2664 2.231928,1.5694 3.043374,2.1604 1.077365,0.7846 1.270646,0.8934 1.587716,0.8936 0.19986,10e-5 0.347904,-0.04 0.469094,-0.1259 z"
|
||||
id="path3047"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
BIN
Resources/graphics/ic_action_nfc/NFC.png
Normal file
After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 5.3 KiB |
753
Resources/graphics/ic_action_qr_code/ic_menu_qr_code.svg
Normal file
@ -0,0 +1,753 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="48px"
|
||||
height="48px"
|
||||
viewBox="0 0 48 48"
|
||||
enable-background="new 0 0 48 48"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="ic_menu_qr_code.svg"><metadata
|
||||
id="metadata231"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs229">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="921"
|
||||
id="namedview227"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.4558186"
|
||||
inkscape:cx="9.2917208"
|
||||
inkscape:cy="14.446251"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect25"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="4.5710001"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect39"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="4.5710001"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect55"
|
||||
height="6.8569999"
|
||||
width="2.2850001"
|
||||
y="4.5710001"
|
||||
x="9.1440001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect33"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="36.57"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect49"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="36.57"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect61"
|
||||
height="6.8569999"
|
||||
width="2.2850001"
|
||||
y="36.57"
|
||||
x="9.1440001" /><rect
|
||||
y="0"
|
||||
x="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect5"
|
||||
height="16"
|
||||
width="2.2850001" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect13"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
x="2.2850001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect15"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="13.714"
|
||||
x="2.2850001" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect23"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect27"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="13.714"
|
||||
x="4.5710001" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect37"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect41"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="13.714"
|
||||
x="6.8569999" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect53"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="9.1440001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect57"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="13.714"
|
||||
x="9.1440001" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect65"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="11.429" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect67"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="13.714"
|
||||
x="11.429" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect75"
|
||||
height="16"
|
||||
width="2.286"
|
||||
x="13.714" /><rect
|
||||
x="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect11"
|
||||
height="16"
|
||||
width="2.2850001"
|
||||
y="32" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect19"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="32"
|
||||
x="2.2850001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect21"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="45.714001"
|
||||
x="2.2850001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect31"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="32"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect35"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="45.714001"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect47"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="32"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect51"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="45.714001"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect59"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="32"
|
||||
x="9.1440001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect63"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="45.714001"
|
||||
x="9.1440001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect71"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="32"
|
||||
x="11.429" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect73"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="45.714001"
|
||||
x="11.429" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect83"
|
||||
height="16"
|
||||
width="2.286"
|
||||
y="32"
|
||||
x="13.714" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect163"
|
||||
height="6.8569999"
|
||||
width="2.2869999"
|
||||
y="4.5710001"
|
||||
x="36.57" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect177"
|
||||
height="6.8569999"
|
||||
width="2.2850001"
|
||||
y="4.5710001"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect191"
|
||||
height="6.8569999"
|
||||
width="2.2869999"
|
||||
y="4.5710001"
|
||||
x="41.143002" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect141"
|
||||
height="16"
|
||||
width="2.2850001"
|
||||
x="32" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect151"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="34.285" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect153"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="13.714"
|
||||
x="34.285" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect161"
|
||||
height="2.2850001"
|
||||
width="2.2869999"
|
||||
x="36.57" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect165"
|
||||
height="2.286"
|
||||
width="2.2869999"
|
||||
y="13.714"
|
||||
x="36.57" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect175"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect179"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="13.714"
|
||||
x="38.856998" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect189"
|
||||
height="2.2850001"
|
||||
width="2.2869999"
|
||||
x="41.143002" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect193"
|
||||
height="2.286"
|
||||
width="2.2869999"
|
||||
y="13.714"
|
||||
x="41.143002" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect203"
|
||||
height="2.2850001"
|
||||
width="2.2839999"
|
||||
x="43.43" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect205"
|
||||
height="2.286"
|
||||
width="2.2839999"
|
||||
y="13.714"
|
||||
x="43.43" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect217"
|
||||
height="16"
|
||||
width="2.286"
|
||||
x="45.714001" /><rect
|
||||
x="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect7"
|
||||
height="4.572"
|
||||
width="2.2850001"
|
||||
y="18.285" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect17"
|
||||
height="2.2869999"
|
||||
width="2.286"
|
||||
y="27.427999"
|
||||
x="2.2850001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect29"
|
||||
height="6.8559999"
|
||||
width="2.286"
|
||||
y="20.570999"
|
||||
x="4.5710001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect43"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="20.570999"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect45"
|
||||
height="4.572"
|
||||
width="2.286"
|
||||
y="25.143"
|
||||
x="6.8569999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect69"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="22.857"
|
||||
x="11.429" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect77"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="18.285"
|
||||
x="13.714" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect79"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="22.857"
|
||||
x="13.714" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect81"
|
||||
height="2.2869999"
|
||||
width="2.286"
|
||||
y="27.427999"
|
||||
x="13.714" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect85"
|
||||
height="4.572"
|
||||
width="2.286"
|
||||
y="20.570999"
|
||||
x="16" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect87"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="2.2850001"
|
||||
x="18.285999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect89"
|
||||
height="18.285999"
|
||||
width="2.286"
|
||||
y="13.714"
|
||||
x="18.285999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect91"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="45.714001"
|
||||
x="18.285999" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect93"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="20.572001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect95"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="9.1429996"
|
||||
x="20.572001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect97"
|
||||
height="6.8569999"
|
||||
width="2.2850001"
|
||||
y="25.143"
|
||||
x="20.572001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect99"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="34.285"
|
||||
x="20.572001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect101"
|
||||
height="9.1429996"
|
||||
width="2.2850001"
|
||||
y="38.856998"
|
||||
x="20.572001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect103"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="6.8569999"
|
||||
x="22.857" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect107"
|
||||
height="6.8569999"
|
||||
width="2.286"
|
||||
y="18.285"
|
||||
x="22.857" /><rect
|
||||
y="0"
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect113"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect117"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="16"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect119"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="22.857"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect121"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="29.715"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect123"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="34.285"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect125"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="45.714001"
|
||||
x="25.143" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect127"
|
||||
height="4.572"
|
||||
width="2.286"
|
||||
y="2.2850001"
|
||||
x="27.427999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect129"
|
||||
height="13.715"
|
||||
width="2.286"
|
||||
y="9.1429996"
|
||||
x="27.427999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect131"
|
||||
height="11.428"
|
||||
width="2.286"
|
||||
y="29.715"
|
||||
x="27.427999" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect135"
|
||||
height="4.572"
|
||||
width="2.286"
|
||||
y="27.427999"
|
||||
x="29.714001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect137"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="34.285"
|
||||
x="29.714001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect139"
|
||||
height="2.286"
|
||||
width="2.286"
|
||||
y="45.714001"
|
||||
x="29.714001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect145"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="22.857"
|
||||
x="32" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect149"
|
||||
height="2.2869999"
|
||||
width="2.2850001"
|
||||
y="41.143002"
|
||||
x="32" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect155"
|
||||
height="6.8559999"
|
||||
width="2.2850001"
|
||||
y="20.570999"
|
||||
x="34.285" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect157"
|
||||
height="4.572"
|
||||
width="2.2850001"
|
||||
y="34.285"
|
||||
x="34.285" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect169"
|
||||
height="2.2869999"
|
||||
width="2.2869999"
|
||||
y="27.427999"
|
||||
x="36.57" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect171"
|
||||
height="4.5700002"
|
||||
width="2.2869999"
|
||||
y="32"
|
||||
x="36.57" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect173"
|
||||
height="9.1429996"
|
||||
width="2.2869999"
|
||||
y="38.856998"
|
||||
x="36.57" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect181"
|
||||
height="2.286"
|
||||
width="2.2850001"
|
||||
y="18.285"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect183"
|
||||
height="4.5700002"
|
||||
width="2.2850001"
|
||||
y="22.857"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect185"
|
||||
height="2.2850001"
|
||||
width="2.2850001"
|
||||
y="34.285"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect187"
|
||||
height="2.2839999"
|
||||
width="2.2850001"
|
||||
y="43.43"
|
||||
x="38.856998" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect195"
|
||||
height="9.1429996"
|
||||
width="2.2869999"
|
||||
y="18.285"
|
||||
x="41.143002" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect197"
|
||||
height="2.2850001"
|
||||
width="2.2869999"
|
||||
y="29.715"
|
||||
x="41.143002" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect199"
|
||||
height="2.2850001"
|
||||
width="2.2869999"
|
||||
y="34.285"
|
||||
x="41.143002" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect201"
|
||||
height="6.855"
|
||||
width="2.2869999"
|
||||
y="38.856998"
|
||||
x="41.143002" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect207"
|
||||
height="2.286"
|
||||
width="2.2839999"
|
||||
y="18.285"
|
||||
x="43.43" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect209"
|
||||
height="6.8569999"
|
||||
width="2.2839999"
|
||||
y="22.857"
|
||||
x="43.43" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect211"
|
||||
height="2.2850001"
|
||||
width="2.2839999"
|
||||
y="32"
|
||||
x="43.43" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect215"
|
||||
height="2.286"
|
||||
width="2.2839999"
|
||||
y="45.714001"
|
||||
x="43.43" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect219"
|
||||
height="2.2850001"
|
||||
width="2.286"
|
||||
y="25.143"
|
||||
x="45.714001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect223"
|
||||
height="4.572"
|
||||
width="2.286"
|
||||
y="34.285"
|
||||
x="45.714001" /><rect
|
||||
style="opacity:0.6;fill:#333333;fill-opacity:1"
|
||||
id="rect225"
|
||||
height="2.2869999"
|
||||
width="2.286"
|
||||
y="41.143002"
|
||||
x="45.714001" />
|
||||
</svg>
|
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 182 KiB |
@ -20,7 +20,7 @@ PLAY_DIR=./
|
||||
# xxxhdpi 192x192.
|
||||
# google play: 512x512
|
||||
|
||||
NAME="icon"
|
||||
NAME="ic_launcher"
|
||||
|
||||
inkscape -w 36 -h 36 -e "$LDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 48 -h 48 -e "$MDPI_DIR/$NAME.png" $NAME.svg
|
||||
@ -30,3 +30,17 @@ inkscape -w 144 -h 144 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 192 -h 192 -e "$XXXDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 512 -h 512 -e "$PLAY_DIR/$NAME.png" $NAME.svg
|
||||
|
||||
# Actionbar Icons
|
||||
# -----------------------
|
||||
# mdpi: 32x32
|
||||
# hdpi: 48x48
|
||||
# xhdpi: 64x64
|
||||
# xxhdpi: 96x96
|
||||
|
||||
for NAME in "ic_action_nfc" "ic_action_qr_code"
|
||||
do
|
||||
inkscape -w 32 -h 32 -e "$MDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 48 -h 48 -e "$HDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 64 -h 64 -e "$XDPI_DIR/$NAME.png" $NAME.svg
|
||||
inkscape -w 96 -h 96 -e "$XXDPI_DIR/$NAME.png" $NAME.svg
|
||||
done
|