diff options
| author | Dominik Schürmann <dominik@dominikschuermann.de> | 2015-02-26 02:06:57 +0100 | 
|---|---|---|
| committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2015-02-26 02:06:57 +0100 | 
| commit | 72acaaa41f88c729b651575a2c014cff11ca0fe4 (patch) | |
| tree | 96875707d11f4b9dceb0c9493f0daa1fb3fcb730 /OpenKeychain/src | |
| parent | a38f84a40169a65bf0eac1e06165a844df9b642c (diff) | |
| download | open-keychain-72acaaa41f88c729b651575a2c014cff11ca0fe4.tar.gz open-keychain-72acaaa41f88c729b651575a2c014cff11ca0fe4.tar.bz2 open-keychain-72acaaa41f88c729b651575a2c014cff11ca0fe4.zip  | |
Fingerprint verification, design fixes for qr code card
Diffstat (limited to 'OpenKeychain/src')
14 files changed, 531 insertions, 70 deletions
diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 6426a229c..29b748410 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -443,6 +443,14 @@                  android:value=".ui.MainActivity" />          </activity>          <activity +            android:name=".ui.CertifyFingerprintActivity" +            android:configChanges="orientation|screenSize|keyboardHidden|keyboard" +            android:label="@string/title_certify_key"> +            <meta-data +                android:name="android.support.PARENT_ACTIVITY" +                android:value=".ui.MainActivity" /> +        </activity> +        <activity              android:name=".ui.QrCodeScanActivity"              android:configChanges="orientation|screenSize|keyboardHidden|keyboard"              android:label="@string/app_name" diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java new file mode 100644 index 000000000..777288e69 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.util.Log; + +public class CertifyFingerprintActivity extends BaseActivity { + +    protected Uri mDataUri; + +    @Override +    public void onCreate(Bundle savedInstanceState) { +        super.onCreate(savedInstanceState); + +        mDataUri = getIntent().getData(); +        if (mDataUri == null) { +            Log.e(Constants.TAG, "Data missing. Should be uri of key!"); +            finish(); +            return; +        } + +        setFullScreenDialogClose(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                finish(); +            } +        }); + +        Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); + +        startFragment(savedInstanceState, mDataUri); +    } + +    @Override +    protected void initLayout() { +        setContentView(R.layout.certify_fingerprint_activity); +    } + +    private void startFragment(Bundle savedInstanceState, Uri dataUri) { +        // However, if we're being restored from a previous state, +        // then we don't need to do anything and should return or else +        // we could end up with overlapping fragments. +        if (savedInstanceState != null) { +            return; +        } + +        // Create an instance of the fragment +        CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(dataUri); + +        // Add the fragment to the 'fragment_container' FrameLayout +        // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! +        getSupportFragmentManager().beginTransaction() +                .replace(R.id.certify_fingerprint_fragment, frag) +                .commitAllowingStateLoss(); +        // do it immediately! +        getSupportFragmentManager().executePendingTransactions(); +    } + +    @Override +    protected void onActivityResult(int requestCode, int resultCode, Intent data) { +        // if a result has been returned, display a notify +        if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { +            OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); +            result.createNotify(this).show(); +        } else { +            super.onActivityResult(requestCode, resultCode, data); +        } +    } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java new file mode 100644 index 000000000..aef705ee9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.util.Log; + + +public class CertifyFingerprintFragment extends LoaderFragment implements +        LoaderManager.LoaderCallbacks<Cursor> { + +    public static final String ARG_DATA_URI = "uri"; + +    private TextView mFingerprint; + +    private static final int LOADER_ID_UNIFIED = 0; + +    private Uri mDataUri; + +    private View mActionNo; +    private View mActionYes; + +    /** +     * Creates new instance of this fragment +     */ +    public static CertifyFingerprintFragment newInstance(Uri dataUri) { +        CertifyFingerprintFragment frag = new CertifyFingerprintFragment(); +        Bundle args = new Bundle(); +        args.putParcelable(ARG_DATA_URI, dataUri); + +        frag.setArguments(args); + +        return frag; +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { +        View root = super.onCreateView(inflater, superContainer, savedInstanceState); +        View view = inflater.inflate(R.layout.certify_fingerprint_fragment, getContainer()); + +        mActionNo = view.findViewById(R.id.certify_fingerprint_button_no); +        mActionYes = view.findViewById(R.id.certify_fingerprint_button_yes); + +        mFingerprint = (TextView) view.findViewById(R.id.certify_fingerprint_fingerprint); + +        mActionNo.setOnClickListener(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                getActivity().finish(); +            } +        }); +        mActionYes.setOnClickListener(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                certify(mDataUri); +            } +        }); + +        return root; +    } + +    @Override +    public void onActivityCreated(Bundle savedInstanceState) { +        super.onActivityCreated(savedInstanceState); + +        Uri dataUri = getArguments().getParcelable(ARG_DATA_URI); +        if (dataUri == null) { +            Log.e(Constants.TAG, "Data missing. Should be Uri of key!"); +            getActivity().finish(); +            return; +        } + +        loadData(dataUri); +    } + +    private void loadData(Uri dataUri) { +        mDataUri = dataUri; + +        Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); + +        // Prepare the loaders. Either re-connect with an existing ones, +        // or start new ones. +        getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); +    } + +    static final String[] UNIFIED_PROJECTION = new String[]{ +            KeyRings._ID, KeyRings.FINGERPRINT, + +    }; +    static final int INDEX_UNIFIED_FINGERPRINT = 1; + +    public Loader<Cursor> onCreateLoader(int id, Bundle args) { +        setContentShown(false); +        switch (id) { +            case LOADER_ID_UNIFIED: { +                Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri); +                return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); +            } + +            default: +                return null; +        } +    } + +    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { +        /* TODO better error handling? May cause problems when a key is deleted, +         * because the notification triggers faster than the activity closes. +         */ +        // Avoid NullPointerExceptions... +        if (data.getCount() == 0) { +            return; +        } +        // Swap the new cursor in. (The framework will take care of closing the +        // old cursor once we return.) +        switch (loader.getId()) { +            case LOADER_ID_UNIFIED: { +                if (data.moveToFirst()) { + +                    byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT); +                    String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob); +                    mFingerprint.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint)); + +                    break; +                } +            } + +        } +        setContentShown(true); +    } + +    /** +     * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. +     * We need to make sure we are no longer using it. +     */ +    public void onLoaderReset(Loader<Cursor> loader) { +    } + +    private void certify(Uri dataUri) { +        long keyId = 0; +        try { +            keyId = new ProviderHelper(getActivity()) +                    .getCachedPublicKeyRing(dataUri) +                    .extractOrGetMasterKeyId(); +        } catch (PgpKeyNotFoundException e) { +            Log.e(Constants.TAG, "key not found!", e); +        } +        Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class); +        certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId}); +        startActivityForResult(certifyIntent, 0); +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java index b24ee84a4..d3c1d971a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java @@ -21,6 +21,7 @@ import android.graphics.Bitmap;  import android.net.Uri;  import android.os.Bundle;  import android.support.v4.app.ActivityCompat; +import android.support.v7.widget.CardView;  import android.view.View;  import android.view.ViewTreeObserver.OnGlobalLayoutListener;  import android.widget.ImageView; @@ -37,7 +38,8 @@ import org.sufficientlysecure.keychain.util.Log;  public class QrCodeViewActivity extends BaseActivity { -    private ImageView mFingerprintQrCode; +    private ImageView mQrCode; +    private CardView mQrCodeLayout;      @Override      public void onCreate(Bundle savedInstanceState) { @@ -61,9 +63,10 @@ public class QrCodeViewActivity extends BaseActivity {              return;          } -        mFingerprintQrCode = (ImageView) findViewById(R.id.qr_code_image); +        mQrCode = (ImageView) findViewById(R.id.qr_code_image); +        mQrCodeLayout = (CardView) findViewById(R.id.qr_code_image_layout); -        mFingerprintQrCode.setOnClickListener(new View.OnClickListener() { +        mQrCodeLayout.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  ActivityCompat.finishAfterTransition(QrCodeViewActivity.this); @@ -87,14 +90,14 @@ public class QrCodeViewActivity extends BaseActivity {              // create a minimal size qr code, we can keep this in ram no problem              final Bitmap qrCode = QrCodeUtils.getQRCodeBitmap(qrCodeContent, 0); -            mFingerprintQrCode.getViewTreeObserver().addOnGlobalLayoutListener( +            mQrCode.getViewTreeObserver().addOnGlobalLayoutListener(                      new OnGlobalLayoutListener() {                          @Override                          public void onGlobalLayout() {                              // create actual bitmap in display dimensions                              Bitmap scaled = Bitmap.createScaledBitmap(qrCode, -                                    mFingerprintQrCode.getWidth(), mFingerprintQrCode.getWidth(), false); -                            mFingerprintQrCode.setImageBitmap(scaled); +                                    mQrCode.getWidth(), mQrCode.getWidth(), false); +                            mQrCode.setImageBitmap(scaled);                          }                      });          } catch (ProviderHelper.NotFoundException e) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index c67fde8e1..e1a8981c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -87,11 +87,10 @@ public class ViewKeyActivity extends BaseActivity implements      private ImageButton mActionEncryptFile;      private ImageButton mActionEncryptText; -    private ImageButton mActionVerify;      private ImageButton mActionNfc;      private FloatingActionButton mFab;      private AspectRatioImageView mPhoto; -    private ImageButton mQrCode; +    private ImageView mQrCode;      private CardView mQrCodeLayout;      // NFC @@ -105,6 +104,7 @@ public class ViewKeyActivity extends BaseActivity implements      private boolean mIsSecret = false;      private boolean mHasEncrypt = false; +    private boolean mIsVerified = false;      @Override      protected void onCreate(Bundle savedInstanceState) { @@ -122,11 +122,10 @@ public class ViewKeyActivity extends BaseActivity implements          mActionEncryptFile = (ImageButton) findViewById(R.id.view_key_action_encrypt_files);          mActionEncryptText = (ImageButton) findViewById(R.id.view_key_action_encrypt_text); -        mActionVerify = (ImageButton) findViewById(R.id.view_key_action_verify);          mActionNfc = (ImageButton) findViewById(R.id.view_key_action_nfc);          mFab = (FloatingActionButton) findViewById(R.id.fab);          mPhoto = (AspectRatioImageView) findViewById(R.id.view_key_photo); -        mQrCode = (ImageButton) findViewById(R.id.view_key_qr_code); +        mQrCode = (ImageView) findViewById(R.id.view_key_qr_code);          mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout);          mDataUri = getIntent().getData(); @@ -159,11 +158,6 @@ public class ViewKeyActivity extends BaseActivity implements                  encrypt(mDataUri, true);              }          }); -        mActionVerify.setOnClickListener(new View.OnClickListener() { -            public void onClick(View view) { -                certify(mDataUri); -            } -        });          mFab.setOnClickListener(new View.OnClickListener() {              @Override @@ -176,7 +170,7 @@ public class ViewKeyActivity extends BaseActivity implements              }          }); -        mQrCode.setOnClickListener(new View.OnClickListener() { +        mQrCodeLayout.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  showQrCodeDialog(); @@ -269,6 +263,10 @@ public class ViewKeyActivity extends BaseActivity implements                      editKey(mDataUri);                      return true;                  } +                case R.id.menu_key_view_certify_fingerprint: { +                    certifyFingeprint(mDataUri); +                    return true; +                }              }          } catch (ProviderHelper.NotFoundException e) {              Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR); @@ -279,8 +277,11 @@ public class ViewKeyActivity extends BaseActivity implements      @Override      public boolean onPrepareOptionsMenu(Menu menu) { -        MenuItem register = menu.findItem(R.id.menu_key_view_edit); -        register.setVisible(mIsSecret); +        MenuItem editKey = menu.findItem(R.id.menu_key_view_edit); +        editKey.setVisible(mIsSecret); +        MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint); +        certifyFingerprint.setVisible(!mIsSecret && !mIsVerified); +          return true;      } @@ -321,6 +322,12 @@ public class ViewKeyActivity extends BaseActivity implements          startActivityForResult(scanQrCode, 0);      } +    private void certifyFingeprint(Uri dataUri) { +        Intent intent = new Intent(this, CertifyFingerprintActivity.class); +        intent.setData(dataUri); +        startActivityForResult(intent, 0); +    } +      private void showQrCodeDialog() {          Intent qrCodeIntent = new Intent(this, QrCodeViewActivity.class); @@ -420,20 +427,6 @@ public class ViewKeyActivity extends BaseActivity implements          startActivityForResult(queryIntent, 0);      } -    private void certify(Uri dataUri) { -        long keyId = 0; -        try { -            keyId = new ProviderHelper(this) -                    .getCachedPublicKeyRing(dataUri) -                    .extractOrGetMasterKeyId(); -        } catch (PgpKeyNotFoundException e) { -            Log.e(Constants.TAG, "key not found!", e); -        } -        Intent certifyIntent = new Intent(this, CertifyKeyActivity.class); -        certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId}); -        startActivityForResult(certifyIntent, 0); -    } -      private void editKey(Uri dataUri) {          Intent editIntent = new Intent(this, EditKeyActivity.class);          editIntent.setData(KeychainContract.KeyRingData.buildSecretKeyRingUri(dataUri)); @@ -641,7 +634,10 @@ public class ViewKeyActivity extends BaseActivity implements                      boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;                      boolean isExpired = !data.isNull(INDEX_EXPIRY)                              && new Date(data.getLong(INDEX_EXPIRY) * 1000).before(new Date()); -                    boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; +                    mIsVerified = data.getInt(INDEX_VERIFIED) > 0; + +                    // re-create options menu based on mIsSecret, mIsVerified +                    supportInvalidateOptionsMenu();                      AsyncTask<String, Void, Bitmap> photoTask =                              new AsyncTask<String, Void, Bitmap>() { @@ -666,7 +662,6 @@ public class ViewKeyActivity extends BaseActivity implements                          mActionEncryptFile.setVisibility(View.GONE);                          mActionEncryptText.setVisibility(View.GONE); -                        mActionVerify.setVisibility(View.GONE);                          mActionNfc.setVisibility(View.GONE);                          mFab.setVisibility(View.GONE);                          mQrCodeLayout.setVisibility(View.GONE); @@ -683,14 +678,10 @@ public class ViewKeyActivity extends BaseActivity implements                          mActionEncryptFile.setVisibility(View.GONE);                          mActionEncryptText.setVisibility(View.GONE); -                        mActionVerify.setVisibility(View.GONE);                          mActionNfc.setVisibility(View.GONE);                          mFab.setVisibility(View.GONE);                          mQrCodeLayout.setVisibility(View.GONE);                      } else if (mIsSecret) { -                        // re-create options menu to see edit button -                        supportInvalidateOptionsMenu(); -                          mStatusText.setText(R.string.view_key_my_key);                          mStatusImage.setVisibility(View.GONE);                          color = getResources().getColor(R.color.primary); @@ -720,7 +711,6 @@ public class ViewKeyActivity extends BaseActivity implements                          mActionEncryptFile.setVisibility(View.VISIBLE);                          mActionEncryptText.setVisibility(View.VISIBLE); -                        mActionVerify.setVisibility(View.GONE);                          // invokeBeam is available from API 21                          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -736,7 +726,7 @@ public class ViewKeyActivity extends BaseActivity implements                          mQrCodeLayout.setVisibility(View.GONE);                          mActionNfc.setVisibility(View.GONE); -                        if (isVerified) { +                        if (mIsVerified) {                              mStatusText.setText(R.string.view_key_verified);                              mStatusImage.setVisibility(View.VISIBLE);                              KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, @@ -744,7 +734,6 @@ public class ViewKeyActivity extends BaseActivity implements                              color = getResources().getColor(R.color.primary);                              photoTask.execute(fingerprint); -                            mActionVerify.setVisibility(View.GONE);                              mFab.setVisibility(View.GONE);                          } else {                              mStatusText.setText(R.string.view_key_unverified); @@ -753,7 +742,6 @@ public class ViewKeyActivity extends BaseActivity implements                                      KeyFormattingUtils.STATE_UNVERIFIED, R.color.icons, true);                              color = getResources().getColor(R.color.android_orange_light); -                            mActionVerify.setVisibility(View.VISIBLE);                              mFab.setVisibility(View.VISIBLE);                          }                      } diff --git a/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml b/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml new file mode 100644 index 000000000..ec91d1455 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/certify_fingerprint_activity.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +    xmlns:card_view="http://schemas.android.com/apk/res-auto" +    xmlns:app="http://schemas.android.com/apk/res-auto" +    android:layout_width="match_parent" +    android:layout_height="match_parent"> + +    <include +        android:id="@+id/toolbar_include" +        layout="@layout/toolbar_standalone" /> + +    <LinearLayout +        android:layout_below="@id/toolbar_include" +        android:layout_width="match_parent" +        android:layout_height="match_parent" +        android:orientation="vertical"> + +        <FrameLayout +            android:id="@+id/content_frame" +            android:layout_width="match_parent" +            android:layout_height="match_parent"> + +            <FrameLayout +                android:id="@+id/certify_fingerprint_fragment" +                android:layout_width="match_parent" +                android:layout_height="match_parent" +                android:orientation="vertical" /> + +        </FrameLayout> + +    </LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml b/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml new file mode 100644 index 000000000..9b6b35012 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/certify_fingerprint_fragment.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +    xmlns:app="http://schemas.android.com/apk/res-auto" +    android:layout_width="match_parent" +    android:layout_height="match_parent"> + +    <ScrollView +        android:layout_width="match_parent" +        android:layout_height="match_parent" +        android:layout_above="@+id/certify_fingerprint_buttons_divider"> + +        <LinearLayout +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:orientation="vertical" +            android:padding="16dp"> + +            <TextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:layout_marginLeft="8dp" +                android:layout_marginRight="8dp" +                android:textAppearance="?android:attr/textAppearanceMedium" +                android:text="@string/certify_fingerprint_text" /> + +            <android.support.v7.widget.CardView +                android:id="@+id/certify_fingerprint_card" +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                app:cardBackgroundColor="@android:color/white" +                app:cardUseCompatPadding="true" +                app:cardCornerRadius="4dp" +                android:layout_gravity="top"> + +                <LinearLayout +                    android:layout_width="match_parent" +                    android:layout_height="wrap_content" +                    android:orientation="vertical"> + +                    <TextView +                        style="@style/CardViewHeader" +                        android:layout_width="wrap_content" +                        android:layout_height="wrap_content" +                        android:text="@string/label_fingerprint" /> + +                    <TextView +                        android:id="@+id/certify_fingerprint_fingerprint" +                        android:paddingLeft="16dp" +                        android:paddingRight="16dp" +                        android:paddingTop="8dp" +                        android:paddingBottom="8dp" +                        android:textSize="20sp" +                        android:layout_width="match_parent" +                        android:layout_height="wrap_content" +                        android:typeface="monospace" +                        android:gravity="center_vertical" /> +                </LinearLayout> + +            </android.support.v7.widget.CardView> + +        </LinearLayout> + +    </ScrollView> + + +    <LinearLayout +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:orientation="horizontal" +        android:layout_alignParentBottom="true" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:id="@+id/certify_fingerprint_buttons"> + +        <TextView +            android:id="@+id/certify_fingerprint_button_no" +            android:paddingLeft="8dp" +            android:paddingRight="8dp" +            android:textAppearance="?android:attr/textAppearanceMedium" +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:layout_weight="1" +            android:text="@string/btn_no" +            android:minHeight="?android:attr/listPreferredItemHeight" +            android:gravity="center_vertical" +            android:clickable="true" +            style="?android:attr/borderlessButtonStyle" +            android:layout_gravity="center_vertical" /> + +        <View +            android:layout_width="1dp" +            android:layout_height="match_parent" +            android:layout_marginTop="8dp" +            android:layout_marginBottom="8dp" +            android:background="?android:attr/listDivider" /> + +        <TextView +            android:id="@+id/certify_fingerprint_button_yes" +            android:paddingLeft="8dp" +            android:paddingRight="8dp" +            android:textAppearance="?android:attr/textAppearanceMedium" +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:layout_weight="1" +            android:text="@string/btn_match" +            android:minHeight="?android:attr/listPreferredItemHeight" +            android:drawablePadding="8dp" +            android:gravity="center_vertical" +            android:clickable="true" +            style="?android:attr/borderlessButtonStyle" +            android:layout_gravity="center_vertical" /> +    </LinearLayout> + +    <View +        android:id="@+id/certify_fingerprint_buttons_divider2" +        android:layout_width="match_parent" +        android:layout_height="1dip" +        android:background="?android:attr/listDivider" +        android:layout_alignBottom="@+id/certify_fingerprint_buttons_text" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" /> + +    <TextView +        android:id="@+id/certify_fingerprint_buttons_text" +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:layout_marginLeft="24dp" +        android:layout_marginRight="24dp" +        android:paddingTop="8dp" +        android:paddingBottom="8dp" +        android:textAppearance="?android:attr/textAppearanceMedium" +        android:text="@string/certify_fingerprint_text2" +        android:layout_above="@+id/certify_fingerprint_buttons" +        android:layout_centerHorizontal="true" /> + +    <View +        android:id="@+id/certify_fingerprint_buttons_divider" +        android:layout_width="match_parent" +        android:layout_height="1dip" +        android:background="?android:attr/listDivider" +        android:layout_alignTop="@+id/certify_fingerprint_buttons_text" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" /> + + + +</RelativeLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/create_key_activity.xml b/OpenKeychain/src/main/res/layout/create_key_activity.xml index e8422fb37..c42fd4d4b 100644 --- a/OpenKeychain/src/main/res/layout/create_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/create_key_activity.xml @@ -7,19 +7,15 @@          android:id="@+id/toolbar_include"          layout="@layout/toolbar_standalone" /> -    <LinearLayout +    <FrameLayout          android:layout_below="@id/toolbar_include" -        android:orientation="vertical"          android:layout_width="match_parent"          android:layout_height="match_parent"> -        <include layout="@layout/notify_area" /> -          <FrameLayout              android:id="@+id/create_key_fragment_container"              android:layout_width="match_parent" -            android:layout_height="match_parent" -            android:orientation="vertical" /> +            android:layout_height="match_parent" /> -    </LinearLayout> +    </FrameLayout>  </RelativeLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml index 189579f91..97eba9cd1 100644 --- a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml @@ -159,7 +159,7 @@              android:minHeight="?android:attr/listPreferredItemHeight"              android:gravity="center_vertical"              android:clickable="true" -            style="@style/SelectableItem" +            style="?android:attr/borderlessButtonStyle"              android:layout_gravity="center_vertical" />          <View @@ -183,7 +183,7 @@              android:drawablePadding="8dp"              android:gravity="center_vertical"              android:clickable="true" -            style="@style/SelectableItem" +            style="?android:attr/borderlessButtonStyle"              android:layout_gravity="center_vertical" />      </LinearLayout> diff --git a/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml index d92988111..026d98004 100644 --- a/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml +++ b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="UTF-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" -    android:layout_width="wrap_content" +    android:layout_width="match_parent"      android:layout_height="match_parent">      <ScrollView @@ -139,7 +139,7 @@              android:drawablePadding="8dp"              android:gravity="center_vertical"              android:clickable="true" -            style="@style/SelectableItem" +            style="?android:attr/borderlessButtonStyle"              android:layout_gravity="center_vertical" />      </LinearLayout>  </RelativeLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/qr_code_activity.xml b/OpenKeychain/src/main/res/layout/qr_code_activity.xml index 126be4c3a..4ce097f40 100644 --- a/OpenKeychain/src/main/res/layout/qr_code_activity.xml +++ b/OpenKeychain/src/main/res/layout/qr_code_activity.xml @@ -1,6 +1,5 @@  <?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" -    xmlns:card_view="http://schemas.android.com/apk/res-auto"      xmlns:app="http://schemas.android.com/apk/res-auto"      android:layout_width="match_parent"      android:layout_height="match_parent"> @@ -21,16 +20,17 @@              android:layout_margin="32dp"              android:layout_width="match_parent"              android:layout_height="wrap_content" -            card_view:cardBackgroundColor="@android:color/white" -            card_view:cardUseCompatPadding="true" -            card_view:cardCornerRadius="4dp"> +            android:clickable="true" +            android:foreground="?android:attr/selectableItemBackground" +            app:cardBackgroundColor="@android:color/white" +            app:cardUseCompatPadding="true" +            app:cardCornerRadius="4dp">              <org.sufficientlysecure.keychain.ui.widget.AspectRatioImageView                  android:id="@+id/qr_code_image" -                app:aspectRatioEnabled="true"                  android:layout_width="match_parent"                  android:layout_height="wrap_content" -                style="?android:attr/borderlessButtonStyle" /> +                app:aspectRatioEnabled="true" />          </android.support.v7.widget.CardView>      </LinearLayout> diff --git a/OpenKeychain/src/main/res/layout/view_key_activity.xml b/OpenKeychain/src/main/res/layout/view_key_activity.xml index 7dd30c22c..e2d153e0d 100644 --- a/OpenKeychain/src/main/res/layout/view_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/view_key_activity.xml @@ -101,14 +101,6 @@                  android:src="@drawable/ic_action_encrypt_text" />              <ImageButton -                android:id="@+id/view_key_action_verify" -                android:layout_width="64dp" -                android:layout_height="64dp" -                android:visibility="invisible" -                style="?android:attr/borderlessButtonStyle" -                android:src="@drawable/ic_action_verified_cutout" /> - -            <ImageButton                  android:id="@+id/view_key_action_nfc"                  android:layout_width="64dp"                  android:layout_height="64dp" @@ -139,15 +131,16 @@              android:layout_marginRight="20dp"              android:layout_width="wrap_content"              android:layout_height="wrap_content" +            android:clickable="true" +            android:foreground="?android:attr/selectableItemBackground"              card_view:cardBackgroundColor="@android:color/white"              card_view:cardUseCompatPadding="true"              card_view:cardCornerRadius="4dp"> -            <ImageButton +            <ImageView                  android:id="@+id/view_key_qr_code"                  android:layout_width="96dp" -                android:layout_height="96dp" -                style="?android:attr/borderlessButtonStyle" /> +                android:layout_height="96dp" />          </android.support.v7.widget.CardView>      </RelativeLayout> diff --git a/OpenKeychain/src/main/res/menu/key_view.xml b/OpenKeychain/src/main/res/menu/key_view.xml index 86f8ea6a2..c724c46a5 100644 --- a/OpenKeychain/src/main/res/menu/key_view.xml +++ b/OpenKeychain/src/main/res/menu/key_view.xml @@ -31,4 +31,10 @@          app:showAsAction="never"          android:title="@string/menu_advanced" /> +    <item +        android:id="@+id/menu_key_view_certify_fingerprint" +        app:showAsAction="never" +        android:visible="false" +        android:title="@string/menu_certify_fingerprint" /> +  </menu>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 067ce20ea..e4b7cdd20 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -78,6 +78,8 @@      <string name="btn_export_to_server">"Upload To Keyserver"</string>      <string name="btn_next">"Next"</string>      <string name="btn_back">"Back"</string> +    <string name="btn_no">"No"</string> +    <string name="btn_match">"Fingerprints are matching"</string>      <string name="btn_lookup_key">"Lookup key"</string>      <string name="btn_share_encrypted_signed">"Encrypt and share message"</string>      <string name="btn_view_cert_key">"View certification key"</string> @@ -107,6 +109,7 @@      <string name="menu_search_cloud">"Search cloud"</string>      <string name="menu_export_all_keys">"Export all keys"</string>      <string name="menu_advanced">"Show advanced info"</string> +    <string name="menu_certify_fingerprint">"Verify via fingerprint comparison"</string>      <!-- label -->      <string name="label_message">"Message"</string> @@ -1124,6 +1127,8 @@      <string name="certs_text">"Only validated self-certificates and validated certificates created with your keys are displayed here."</string>      <string name="section_uids_to_certify">"Identities for "</string>      <string name="certify_text">"The keys you are importing contain “identities”: names and emails. Select exactly those for certification which match what you expected."</string> +    <string name="certify_fingerprint_text">"Compare the displayed fingerprint, character by character, with the one displayed on your partners device."</string> +    <string name="certify_fingerprint_text2">"Do the displayed fingerprints match?"</string>      <string name="label_revocation">"Revocation Reason"</string>      <string name="label_verify_status">"Verification Status"</string>      <string name="label_cert_type">"Type"</string>  | 
