diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-01-03 12:24:08 +0100 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-01-03 12:24:08 +0100 |
commit | 15be9fc99b55889a175debb57185a6a75a34b1a3 (patch) | |
tree | dbbc33a436f360ac7ee70e6c54fd2a33abaf2430 /OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui | |
parent | 9576aeabca5453578f297d3546f2d3526eb377de (diff) | |
download | open-keychain-15be9fc99b55889a175debb57185a6a75a34b1a3.tar.gz open-keychain-15be9fc99b55889a175debb57185a6a75a34b1a3.tar.bz2 open-keychain-15be9fc99b55889a175debb57185a6a75a34b1a3.zip |
integrate NFC into key view and import activities
Diffstat (limited to 'OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui')
4 files changed, 252 insertions, 241 deletions
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 37edc8f49..f83d469ac 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; import java.util.List; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; @@ -29,21 +28,23 @@ import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; import org.sufficientlysecure.keychain.util.Log; - +import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.nfc.NdefMessage; +import android.nfc.NfcAdapter; import android.os.Bundle; 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.view.View; import android.widget.ArrayAdapter; import android.widget.Toast; - import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar.OnNavigationListener; import com.actionbarsherlock.app.SherlockFragmentActivity; @@ -345,7 +346,8 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD); String toastMessage; if (added > 0 && updated > 0) { - toastMessage = getString(R.string.keys_added_and_updated, added, updated); + toastMessage = getString(R.string.keys_added_and_updated, added, + updated); } else if (added > 0) { toastMessage = getString(R.string.keys_added, added); } else if (updated > 0) { @@ -409,4 +411,43 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa .show(); } + /** + * NFC + */ + @Override + public void onResume() { + super.onResume(); + // Check to see that the Activity started due to an Android Beam + if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { + handleActionNdefDiscovered(getIntent()); + } + } + + /** + * NFC + */ + @Override + public void onNewIntent(Intent intent) { + // onResume gets called after this to handle the intent + setIntent(intent); + } + + /** + * NFC: Parses the NDEF Message from the intent and prints to the TextView + */ + @SuppressLint("NewApi") + void handleActionNdefDiscovered(Intent intent) { + Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); + // only one message sent during the beam + NdefMessage msg = (NdefMessage) rawMsgs[0]; + // record 0 contains the MIME type, record 1 is the AAR, if present + byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload(); + + Intent importIntent = new Intent(this, ImportKeysActivity.class); + importIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY); + importIntent.putExtra(ImportKeysActivity.EXTRA_KEY_BYTES, receivedKeyringBytes); + + handleActions(null, importIntent); + } + } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java index 4a628a3c3..ad63f022d 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyViewActivity.java @@ -1,6 +1,6 @@ /* - * Copyright (C) 2013 Bahtiar 'kalkin' Gadimov * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2013 Bahtiar 'kalkin' Gadimov * * 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 @@ -30,21 +30,34 @@ import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; +import android.nfc.NdefMessage; +import android.nfc.NdefRecord; +import android.nfc.NfcAdapter; +import android.nfc.NfcAdapter.CreateNdefMessageCallback; +import android.nfc.NfcAdapter.OnNdefPushCompleteCallback; +import android.nfc.NfcEvent; +import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; import android.text.format.DateFormat; import android.widget.TextView; +import android.widget.Toast; -import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; -public class KeyViewActivity extends SherlockFragmentActivity { +@SuppressLint("NewApi") +public class KeyViewActivity extends SherlockFragmentActivity implements CreateNdefMessageCallback, + OnNdefPushCompleteCallback { private Uri mDataUri; private PGPPublicKey mPublicKey; @@ -54,6 +67,11 @@ public class KeyViewActivity extends SherlockFragmentActivity { private TextView mExpiry; private TextView mCreation; + // NFC + private NfcAdapter mNfcAdapter; + private byte[] mSharedKeyringBytes; + private static final int NFC_SENT = 1; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -77,6 +95,7 @@ public class KeyViewActivity extends SherlockFragmentActivity { } else { Log.d(Constants.TAG, "uri: " + mDataUri); loadData(mDataUri); + initNfc(); } } @@ -154,12 +173,14 @@ public class KeyViewActivity extends SherlockFragmentActivity { return true; case R.id.menu_key_view_share_nfc: // get master key id using row id - long masterKeyId2 = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + // long masterKeyId2 = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + // + // Intent nfcIntent = new Intent(this, ShareNfcBeamActivity.class); + // nfcIntent.setAction(ShareNfcBeamActivity.ACTION_SHARE_KEYRING_WITH_NFC); + // nfcIntent.putExtra(ShareNfcBeamActivity.EXTRA_MASTER_KEY_ID, masterKeyId2); + // startActivityForResult(nfcIntent, 0); - Intent nfcIntent = new Intent(this, ShareNfcBeamActivity.class); - nfcIntent.setAction(ShareNfcBeamActivity.ACTION_SHARE_KEYRING_WITH_NFC); - nfcIntent.putExtra(ShareNfcBeamActivity.EXTRA_MASTER_KEY_ID, masterKeyId2); - startActivityForResult(nfcIntent, 0); + shareNfc(); return true; case R.id.menu_key_view_delete: @@ -191,8 +212,10 @@ public class KeyViewActivity extends SherlockFragmentActivity { mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(mPublicKey)); } + /** + * TODO: does this duplicate functionality from elsewhere? put in helper! + */ private String[] splitUserId(String userId) { - String[] result = new String[] { "", "", "" }; Log.v("UserID", userId); @@ -219,7 +242,6 @@ public class KeyViewActivity extends SherlockFragmentActivity { // TODO: use data uri! long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); - // get public keyring as ascii armored string ArrayList<String> keyringArmored = ProviderHelper.getPublicKeyRingsAsArmoredString(this, new long[] { masterKeyId }); @@ -242,6 +264,79 @@ public class KeyViewActivity extends SherlockFragmentActivity { ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(keyringArmored .get(0)); - dialog.show(getSupportFragmentManager(), "qrCodeShareDialog"); + dialog.show(getSupportFragmentManager(), "shareQrCodeDialog"); + } + + private void shareNfc() { + ShareNfcDialogFragment dialog = ShareNfcDialogFragment.newInstance(); + dialog.show(getSupportFragmentManager(), "shareNfcDialog"); + } + + /** + * NFC: Initialize NFC sharing if OS and device supports it + */ + private void initNfc() { + // check if NFC Beam is supported (>= Android 4.1) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + // Check for available NFC Adapter + mNfcAdapter = NfcAdapter.getDefaultAdapter(this); + if (mNfcAdapter != null) { + // init nfc + // TODO: use data uri! + long keyRingRowId = Long.valueOf(mDataUri.getLastPathSegment()); + long masterKeyId = ProviderHelper.getPublicMasterKeyId(this, keyRingRowId); + + // get public keyring as byte array + mSharedKeyringBytes = ProviderHelper.getPublicKeyRingsAsByteArray(this, + new long[] { masterKeyId }); + + // Register callback to set NDEF message + mNfcAdapter.setNdefPushMessageCallback(this, this); + // Register callback to listen for message-sent success + mNfcAdapter.setOnNdefPushCompleteCallback(this, this); + } + } + } + + /** + * NFC: Implementation for the CreateNdefMessageCallback interface + */ + @Override + public NdefMessage createNdefMessage(NfcEvent event) { + /** + * When a device receives a push with an AAR in it, the application specified in the AAR is + * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to + * guarantee that this activity starts when receiving a beamed message. For now, this code + * uses the tag dispatch system. + */ + NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME, + mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME)); + return msg; } + + /** + * NFC: Implementation for the OnNdefPushCompleteCallback interface + */ + @Override + public void onNdefPushComplete(NfcEvent arg0) { + // A handler is needed to send messages to the activity when this + // callback occurs, because it happens from a binder thread + mNfcHandler.obtainMessage(NFC_SENT).sendToTarget(); + } + + /** + * NFC: This handler receives a message from onNdefPushComplete + */ + private final Handler mNfcHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NFC_SENT: + Toast.makeText(getApplicationContext(), R.string.nfc_successfull, Toast.LENGTH_LONG) + .show(); + break; + } + } + }; + } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ShareNfcBeamActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ShareNfcBeamActivity.java deleted file mode 100644 index db6a156c7..000000000 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ShareNfcBeamActivity.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.sufficientlysecure.keychain.ui; - -import org.sufficientlysecure.htmltextview.HtmlTextView; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ActionBarHelper; -import org.sufficientlysecure.keychain.provider.ProviderHelper; - -import android.annotation.TargetApi; -import android.content.Intent; -import android.nfc.NdefMessage; -import android.nfc.NdefRecord; -import android.nfc.NfcAdapter; -import android.nfc.NfcAdapter.CreateNdefMessageCallback; -import android.nfc.NfcAdapter.OnNdefPushCompleteCallback; -import android.nfc.NfcEvent; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Parcelable; -import android.provider.Settings; -import android.widget.Toast; - -import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuInflater; -import com.actionbarsherlock.view.MenuItem; - -@TargetApi(Build.VERSION_CODES.JELLY_BEAN) -public class ShareNfcBeamActivity extends SherlockFragmentActivity implements - CreateNdefMessageCallback, OnNdefPushCompleteCallback { - public static final String ACTION_SHARE_KEYRING_WITH_NFC = Constants.INTENT_PREFIX - + "SHARE_KEYRING_WITH_NFC"; - - public static final String EXTRA_MASTER_KEY_ID = "master_key_id"; - - NfcAdapter mNfcAdapter; - - byte[] mSharedKeyringBytes; - - private static final int MESSAGE_SENT = 1; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { - Toast.makeText(this, - getString(R.string.error) + ": " + getString(R.string.error_jelly_bean_needed), - Toast.LENGTH_LONG).show(); - finish(); - } else { - // Check for available NFC Adapter - mNfcAdapter = NfcAdapter.getDefaultAdapter(this); - if (mNfcAdapter == null) { - Toast.makeText(this, - getString(R.string.error) + ": " + getString(R.string.error_nfc_needed), - Toast.LENGTH_LONG).show(); - finish(); - } else { - // handle actions after verifying that nfc works... - handleActions(getIntent()); - } - } - } - - protected void handleActions(Intent intent) { - String action = intent.getAction(); - Bundle extras = intent.getExtras(); - - if (extras == null) { - extras = new Bundle(); - } - - if (ACTION_SHARE_KEYRING_WITH_NFC.equals(action)) { - long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID); - - // get public keyring as byte array - mSharedKeyringBytes = ProviderHelper.getPublicKeyRingsAsByteArray(this, - new long[] { masterKeyId }); - - // Register callback to set NDEF message - mNfcAdapter.setNdefPushMessageCallback(this, this); - // Register callback to listen for message-sent success - mNfcAdapter.setOnNdefPushCompleteCallback(this, this); - } - } - - /** - * Parses the NDEF Message from the intent and prints to the TextView - */ - void handleActionNdefDiscovered(Intent intent) { - Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); - // only one message sent during the beam - NdefMessage msg = (NdefMessage) rawMsgs[0]; - // record 0 contains the MIME type, record 1 is the AAR, if present - byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload(); - - Intent importIntent = new Intent(this, ImportKeysActivity.class); - importIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY); - importIntent.putExtra(ImportKeysActivity.EXTRA_KEY_BYTES, receivedKeyringBytes); - - finish(); - - startActivity(importIntent); - } - - private void buildView() { - setContentView(R.layout.share_nfc_beam); - - HtmlTextView aboutTextView = (HtmlTextView) findViewById(R.id.nfc_beam_text); - - // load html from raw resource (Parsing handled by HtmlTextView library) - aboutTextView.setHtmlFromRawResource(this, R.raw.nfc_beam_share); - - // no flickering when clicking textview for Android < 4 - aboutTextView.setTextColor(getResources().getColor(android.R.color.black)); - - // set actionbar without home button if called from another app - ActionBarHelper.setBackButton(this); - } - - /** - * Implementation for the CreateNdefMessageCallback interface - */ - @Override - public NdefMessage createNdefMessage(NfcEvent event) { - /** - * When a device receives a push with an AAR in it, the application specified in the AAR is - * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to - * guarantee that this activity starts when receiving a beamed message. For now, this code - * uses the tag dispatch system. - */ - NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME, - mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME)); - return msg; - } - - /** - * Implementation for the OnNdefPushCompleteCallback interface - */ - @Override - public void onNdefPushComplete(NfcEvent arg0) { - // A handler is needed to send messages to the activity when this - // callback occurs, because it happens from a binder thread - mHandler.obtainMessage(MESSAGE_SENT).sendToTarget(); - } - - /** This handler receives a message from onNdefPushComplete */ - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MESSAGE_SENT: - Toast.makeText(getApplicationContext(), R.string.nfc_successfull, Toast.LENGTH_LONG) - .show(); - break; - } - } - }; - - @Override - public void onResume() { - super.onResume(); - // Check to see that the Activity started due to an Android Beam - if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { - handleActionNdefDiscovered(getIntent()); - } else { - // build view only when sending nfc, not when receiving, as it gets directly into Import - // activity on receiving - buildView(); - } - } - - @Override - public void onNewIntent(Intent intent) { - // onResume gets called after this to handle the intent - setIntent(intent); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getSupportMenuInflater(); - inflater.inflate(R.menu.nfc_beam, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - - case android.R.id.home: - // app icon in Action Bar clicked; go to KeyListPublicActivity - Intent intent = new Intent(this, KeyListPublicActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - return true; - - case R.id.menu_settings: - Intent intentSettings = new Intent(Settings.ACTION_NFCSHARING_SETTINGS); - startActivity(intentSettings); - return true; - - default: - return super.onOptionsItemSelected(item); - } - } -} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java new file mode 100644 index 000000000..1a19390ad --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2013 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.dialog; + +import org.sufficientlysecure.htmltextview.HtmlTextView; +import org.sufficientlysecure.keychain.R; + +import android.annotation.TargetApi; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.nfc.NfcAdapter; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentActivity; + +@TargetApi(Build.VERSION_CODES.JELLY_BEAN) +public class ShareNfcDialogFragment extends DialogFragment { + + /** + * Creates new instance of this fragment + */ + public static ShareNfcDialogFragment newInstance() { + ShareNfcDialogFragment frag = new ShareNfcDialogFragment(); + + return frag; + } + + /** + * Creates dialog + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final FragmentActivity activity = getActivity(); + + AlertDialog.Builder alert = new AlertDialog.Builder(activity); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setCancelable(true); + + alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + dismiss(); + } + }); + + HtmlTextView textView = new HtmlTextView(getActivity()); + textView.setPadding(8, 8, 8, 8); + alert.setView(textView); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + textView.setText(getString(R.string.error) + ": " + + getString(R.string.error_jelly_bean_needed)); + } else { + // check if NFC Adapter is available + NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); + if (nfcAdapter == null) { + textView.setText(getString(R.string.error) + ": " + + getString(R.string.error_nfc_needed)); + } else { + // nfc works... + textView.setHtmlFromRawResource(getActivity(), R.raw.nfc_beam_share); + + alert.setNegativeButton(R.string.menu_beam_preferences, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + Intent intentSettings = new Intent( + Settings.ACTION_NFCSHARING_SETTINGS); + startActivity(intentSettings); + } + }); + } + } + + // no flickering when clicking textview for Android < 4 + // aboutTextView.setTextColor(getResources().getColor(android.R.color.black)); + + return alert.create(); + } +}
\ No newline at end of file |