diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-01-07 15:56:56 +0100 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-01-07 15:56:56 +0100 |
commit | 9758cb673f7db8c9a5e6951a1afadaaa85b787d6 (patch) | |
tree | eae4fb8739b2aa270bb7890a7a18546f5338a3a5 /APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java | |
parent | 05778fd4827fde2bd56686c2fa007adc00ba8176 (diff) | |
download | open-keychain-9758cb673f7db8c9a5e6951a1afadaaa85b787d6.tar.gz open-keychain-9758cb673f7db8c9a5e6951a1afadaaa85b787d6.tar.bz2 open-keychain-9758cb673f7db8c9a5e6951a1afadaaa85b787d6.zip |
Externalize all import actions into ImportKeysActivity
Diffstat (limited to 'APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java')
-rw-r--r-- | APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java | 501 |
1 files changed, 501 insertions, 0 deletions
diff --git a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java new file mode 100644 index 000000000..bb40d1033 --- /dev/null +++ b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de> + * Copyright (C) 2011 Senecaso + * + * 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.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.compatibility.DialogFragmentWorkaround; +import org.thialfihar.android.apg.helper.OtherHelper; +import org.thialfihar.android.apg.service.ApgIntentServiceHandler; +import org.thialfihar.android.apg.service.ApgIntentService; +import org.thialfihar.android.apg.R; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; + +import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; +import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; +import org.thialfihar.android.apg.util.Log; + +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentResult; + +public class ImportKeysActivity extends SherlockFragmentActivity { + + public static final String ACTION = Constants.INTENT_PREFIX + "IMPORT"; + public static final String ACTION_IMPORT_FROM_FILE = Constants.INTENT_PREFIX + + "IMPORT_FROM_FILE"; + public static final String ACTION_IMPORT_FROM_QR_CODE = Constants.INTENT_PREFIX + + "IMPORT_FROM_QR_CODE"; + public static final String ACTION_IMPORT_FROM_NFC = Constants.INTENT_PREFIX + "IMPORT_FROM_NFC"; + + // only used by IMPORT_AND_RETURN + public static final String EXTRA_TEXT = "text"; + + protected String mImportFilename = Constants.path.APP_DIR + "/"; + + // public static final String EXTRA_KEY_ID = "keyId"; + + protected String mImportData; + protected boolean mDeleteAfterImport = false; + + FileDialogFragment mFileDialog; + + private TextView mContentView; + + private String mScannedContent; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.import_keys); + mContentView = (TextView) findViewById(R.id.import_from_qr_code_content); + + // set actionbar without home button if called from another app + OtherHelper.setActionBarBackButton(this); + + handleActions(getIntent()); + } + + /** + * ActionBar menu is created based on class variables to change it at runtime + * + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(1, Id.menu.option.import_from_file, 0, R.string.menu_importFromFile) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(1, Id.menu.option.import_from_qr_code, 1, R.string.menu_importFromQrCode) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(1, Id.menu.option.import_from_nfc, 2, R.string.menu_importFromNfc) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + + case android.R.id.home: + // app icon in Action Bar clicked; go home + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + return true; + + case Id.menu.option.import_from_file: + showImportKeysDialog(); + + return true; + + case Id.menu.option.import_from_qr_code: + importFromQrCode(); + + return true; + + case Id.menu.option.import_from_nfc: + + return true; + + default: + return super.onOptionsItemSelected(item); + + } + } + + protected void handleActions(Intent intent) { + String action = intent.getAction(); + Bundle extras = intent.getExtras(); + + if (extras == null) { + extras = new Bundle(); + } + + /** + * Android Standard Actions + */ + if (Intent.ACTION_VIEW.equals(action)) { + // Android's Action when opening file associated to APG (see AndroidManifest.xml) + // override action to delegate it to APGs ACTION_IMPORT + action = ACTION; + } + + /** + * APG's own Actions + */ + if (ACTION.equals(action)) { + if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { + mImportFilename = intent.getData().getPath(); + } else { + mImportData = intent.getStringExtra(EXTRA_TEXT); + } + importKeys(); + } else if (ACTION_IMPORT_FROM_FILE.equals(action)) { + if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { + mImportFilename = intent.getData().getPath(); + } + showImportKeysDialog(); + } else if (ACTION_IMPORT_FROM_QR_CODE.equals(action)) { + importFromQrCode(); + } else if (ACTION_IMPORT_FROM_NFC.equals(action)) { + + } + } + + private void importFromQrCode() { + new IntentIntegrator(this).initiateScan(); + } + + /** + * Show to dialog from where to import keys + */ + public void showImportKeysDialog() { + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Log.d(Constants.TAG, "FileDialogFragment.MESSAGE_OKAY"); + Bundle data = message.getData(); + mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + + mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED); + importKeys(); + } + } + }; + + // Create a new Messenger for the communication back + final Messenger messenger = new Messenger(returnHandler); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_importKeys), + getString(R.string.specifyFileToImportFrom), mImportFilename, null, + Id.request.filename); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + }); + } + + /** + * Import keys with mImportData + */ + public void importKeys() { + Log.d(Constants.TAG, "importKeys started"); + + // Send all information needed to service to import key in other thread + Intent intent = new Intent(this, ApgIntentService.class); + + intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_IMPORT_KEY); + + // fill values for this action + Bundle data = new Bundle(); + + // TODO + data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.secret_key); + + if (mImportData != null) { + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES); + data.putByteArray(ApgIntentService.IMPORT_BYTES, mImportData.getBytes()); + } else { + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_FILE); + data.putString(ApgIntentService.IMPORT_FILENAME, mImportFilename); + } + + intent.putExtra(ApgIntentService.EXTRA_DATA, data); + + // Message is received after importing is done in ApgService + ApgIntentServiceHandler saveHandler = new ApgIntentServiceHandler(this, + R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + int added = returnData.getInt(ApgIntentService.RESULT_IMPORT_ADDED); + int updated = returnData.getInt(ApgIntentService.RESULT_IMPORT_UPDATED); + int bad = returnData.getInt(ApgIntentService.RESULT_IMPORT_BAD); + String toastMessage; + if (added > 0 && updated > 0) { + toastMessage = getString(R.string.keysAddedAndUpdated, added, updated); + } else if (added > 0) { + toastMessage = getString(R.string.keysAdded, added); + } else if (updated > 0) { + toastMessage = getString(R.string.keysUpdated, updated); + } else { + toastMessage = getString(R.string.noKeysAddedOrUpdated); + } + Toast.makeText(ImportKeysActivity.this, toastMessage, Toast.LENGTH_SHORT) + .show(); + if (bad > 0) { + AlertDialog.Builder alert = new AlertDialog.Builder(ImportKeysActivity.this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(ImportKeysActivity.this.getString( + R.string.badKeysEncountered, bad)); + + alert.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + alert.setCancelable(true); + alert.create().show(); + } else if (mDeleteAfterImport) { + // everything went well, so now delete, if that was turned on + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mImportFilename); + deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); + } + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(ApgIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + // private void importAndSignOld(final long keyId, final String expectedFingerprint) { + // if (expectedFingerprint != null && expectedFingerprint.length() > 0) { + // + // Thread t = new Thread() { + // @Override + // public void run() { + // try { + // // TODO: display some sort of spinner here while the user waits + // + // // TODO: there should be only 1 + // HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]); + // String encodedKey = server.get(keyId); + // + // PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream( + // encodedKey.getBytes())); + // if (keyring != null && keyring instanceof PGPPublicKeyRing) { + // PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring; + // + // // make sure the fingerprints match before we cache this thing + // String actualFingerprint = PGPHelper.convertToHex(publicKeyRing + // .getPublicKey().getFingerprint()); + // if (expectedFingerprint.equals(actualFingerprint)) { + // // store the signed key in our local cache + // int retval = PGPMain.storeKeyRingInCache(publicKeyRing); + // if (retval != Id.return_value.ok + // && retval != Id.return_value.updated) { + // status.putString(EXTRA_ERROR, + // "Failed to store signed key in local cache"); + // } else { + // Intent intent = new Intent(ImportFromQRCodeActivity.this, + // SignKeyActivity.class); + // intent.putExtra(EXTRA_KEY_ID, keyId); + // startActivityForResult(intent, Id.request.sign_key); + // } + // } else { + // status.putString( + // EXTRA_ERROR, + // "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key."); + // } + // } + // } catch (QueryException e) { + // Log.e(TAG, "Failed to query KeyServer", e); + // status.putString(EXTRA_ERROR, "Failed to query KeyServer"); + // status.putInt(Constants.extras.STATUS, Id.message.done); + // } catch (IOException e) { + // Log.e(TAG, "Failed to query KeyServer", e); + // status.putString(EXTRA_ERROR, "Failed to query KeyServer"); + // status.putInt(Constants.extras.STATUS, Id.message.done); + // } + // } + // }; + // + // t.setName("KeyExchange Download Thread"); + // t.setDaemon(true); + // t.start(); + // } + // } + + public void scanAgainOnClick(View view) { + new IntentIntegrator(this).initiateScan(); + } + + public void finishOnClick(View view) { + finish(); + } + + public void importOnClick(View view) { + Log.d(Constants.TAG, "import key started"); + + if (mScannedContent != null) { + // Send all information needed to service to import key in other thread + Intent intent = new Intent(this, ApgIntentService.class); + + intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_IMPORT_KEY); + + // fill values for this action + Bundle data = new Bundle(); + + data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.public_key); + + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES); + data.putByteArray(ApgIntentService.IMPORT_BYTES, mScannedContent.getBytes()); + + intent.putExtra(ApgIntentService.EXTRA_DATA, data); + + // Message is received after importing is done in ApgService + ApgIntentServiceHandler saveHandler = new ApgIntentServiceHandler(this, + R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + int added = returnData.getInt(ApgIntentService.RESULT_IMPORT_ADDED); + int updated = returnData.getInt(ApgIntentService.RESULT_IMPORT_UPDATED); + int bad = returnData.getInt(ApgIntentService.RESULT_IMPORT_BAD); + String toastMessage; + if (added > 0 && updated > 0) { + toastMessage = getString(R.string.keysAddedAndUpdated, added, updated); + } else if (added > 0) { + toastMessage = getString(R.string.keysAdded, added); + } else if (updated > 0) { + toastMessage = getString(R.string.keysUpdated, updated); + } else { + toastMessage = getString(R.string.noKeysAddedOrUpdated); + } + Toast.makeText(ImportKeysActivity.this, toastMessage, Toast.LENGTH_SHORT) + .show(); + if (bad > 0) { + AlertDialog.Builder alert = new AlertDialog.Builder( + ImportKeysActivity.this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(ImportKeysActivity.this.getString( + R.string.badKeysEncountered, bad)); + + alert.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + alert.setCancelable(true); + alert.create().show(); + } + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(ApgIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + } + + public void signAndUploadOnClick(View view) { + // first, import! + importOnClick(view); + + // TODO: implement sign and upload! + Toast.makeText(ImportKeysActivity.this, "Not implemented right now!", Toast.LENGTH_SHORT) + .show(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.filename: { + if (resultCode == RESULT_OK && data != null) { + try { + String path = data.getData().getPath(); + Log.d(Constants.TAG, "path=" + path); + + // set filename used in export/import dialogs + mFileDialog.setFilename(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); + } + } + return; + } + case IntentIntegrator.REQUEST_CODE: { + IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, + data); + if (scanResult != null && scanResult.getFormatName() != null) { + + mScannedContent = scanResult.getContents(); + + mContentView.setText(mScannedContent); + // String[] bits = scanResult.getContents().split(","); + // if (bits.length != 2) { + // return; // dont know how to handle this. Not a valid code + // } + // + // long keyId = Long.parseLong(bits[0]); + // String expectedFingerprint = bits[1]; + + // importAndSign(keyId, expectedFingerprint); + } + + break; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + } + } + } +} |