diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-09-19 02:02:51 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-09-19 02:02:51 +0200 |
commit | 3c4cb1c2d31ff472dc09d4f71f3f5e9af7547cdd (patch) | |
tree | d8d7ad9ea2b8fac8c988ec38885d4645242c5168 /OpenPGP-Keychain | |
parent | 4c461c1b445eb339382b5ffd174e6d19b93f25d0 (diff) | |
download | open-keychain-3c4cb1c2d31ff472dc09d4f71f3f5e9af7547cdd.tar.gz open-keychain-3c4cb1c2d31ff472dc09d4f71f3f5e9af7547cdd.tar.bz2 open-keychain-3c4cb1c2d31ff472dc09d4f71f3f5e9af7547cdd.zip |
Work on new Import activity
Diffstat (limited to 'OpenPGP-Keychain')
20 files changed, 655 insertions, 234 deletions
diff --git a/OpenPGP-Keychain/res/layout/file_dialog.xml b/OpenPGP-Keychain/res/layout/file_dialog.xml index c95f874a5..e33216042 100644 --- a/OpenPGP-Keychain/res/layout/file_dialog.xml +++ b/OpenPGP-Keychain/res/layout/file_dialog.xml @@ -31,13 +31,20 @@ android:id="@+id/input" android:layout_width="0dip" android:layout_height="wrap_content" - android:layout_weight="1" /> + android:layout_weight="1" + android:gravity="top|left" + android:inputType="textMultiLine|textUri" + android:lines="2" + android:maxLines="6" + android:minLines="2" + android:scrollbars="vertical" /> <ImageButton android:id="@+id/btn_browse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" + android:contentDescription="@string/filemanager_titleOpen" android:src="@drawable/ic_menu_filebrowser" /> </LinearLayout> diff --git a/OpenPGP-Keychain/res/layout/import_keys.xml b/OpenPGP-Keychain/res/layout/import_keys.xml index 1c2dbd0c7..ae391e2fd 100644 --- a/OpenPGP-Keychain/res/layout/import_keys.xml +++ b/OpenPGP-Keychain/res/layout/import_keys.xml @@ -4,8 +4,17 @@ android:layout_height="wrap_content" android:layout_centerHorizontal="true" > + <FrameLayout + android:id="@+id/import_navigation_fragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:orientation="vertical" + android:paddingLeft="4dp" + android:paddingRight="4dp" /> + <LinearLayout - android:id="@+id/import_from_qr_code_footer" + android:id="@+id/import_footer" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" @@ -14,50 +23,29 @@ android:paddingRight="10dp" > <Button - android:id="@+id/import_from_qr_code_import" + android:id="@+id/import_import" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="importOnClick" - android:text="@string/import_from_qr_code_import" /> + android:text="@string/import_import" /> <Button - android:id="@+id/import_from_qr_code_import_sign_and_upload" + android:id="@+id/import_sign_and_upload" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="signAndUploadOnClick" - android:text="@string/import_from_qr_code_import_sign_and_upload" /> - - <Button - android:id="@+id/import_from_qr_code_finish" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:onClick="finishOnClick" - android:text="@string/import_from_qr_code_finish" /> + android:text="@string/import_sign_and_upload" /> </LinearLayout> - <ScrollView + <FrameLayout + android:id="@+id/import_keys_list_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_above="@id/import_from_qr_code_footer" - android:fillViewport="true" > - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:paddingLeft="12dp" - android:paddingRight="12dp" > - - <LinearLayout - android:id="@+id/import_keys_list_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="16dp" - android:orientation="vertical" - android:paddingLeft="4dp" - android:paddingRight="4dp" > - </LinearLayout> - </LinearLayout> - </ScrollView> + android:layout_above="@+id/import_footer" + android:layout_alignParentLeft="true" + android:layout_below="@+id/import_navigation_fragment" + android:orientation="vertical" + android:paddingLeft="4dp" + android:paddingRight="4dp" /> </RelativeLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/layout/import_keys_file_fragment.xml b/OpenPGP-Keychain/res/layout/import_keys_file_fragment.xml new file mode 100644 index 000000000..5093e412f --- /dev/null +++ b/OpenPGP-Keychain/res/layout/import_keys_file_fragment.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <EditText + android:id="@+id/import_keys_file_input" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="top|left" + android:inputType="textMultiLine|textUri" + android:lines="2" + android:maxLines="6" + android:minLines="2" + android:scrollbars="vertical" /> + + <ImageButton + android:id="@+id/import_keys_file_browse" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:contentDescription="@string/filemanager_titleOpen" + android:src="@drawable/ic_menu_filebrowser" /> + +</LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml b/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml new file mode 100644 index 000000000..9c7e53cf8 --- /dev/null +++ b/OpenPGP-Keychain/res/layout/import_keys_keyserver_fragment.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + +</LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/layout/import_keys_nfc_fragment.xml b/OpenPGP-Keychain/res/layout/import_keys_nfc_fragment.xml new file mode 100644 index 000000000..1b782c4e8 --- /dev/null +++ b/OpenPGP-Keychain/res/layout/import_keys_nfc_fragment.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <Button + android:id="@+id/import_nfc_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/menu_importFromNfc" /> + +</LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/layout/import_keys_qr_code_fragment.xml b/OpenPGP-Keychain/res/layout/import_keys_qr_code_fragment.xml new file mode 100644 index 000000000..46b5fb458 --- /dev/null +++ b/OpenPGP-Keychain/res/layout/import_keys_qr_code_fragment.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <Button + android:id="@+id/import_qrcode_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/menu_importFromQrCode" /> + +</LinearLayout>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/values/arrays.xml b/OpenPGP-Keychain/res/values/arrays.xml index 950a70821..dc9de0f38 100644 --- a/OpenPGP-Keychain/res/values/arrays.xml +++ b/OpenPGP-Keychain/res/values/arrays.xml @@ -49,4 +49,11 @@ <item>@string/key_size_2048</item> <item>@string/key_size_4096</item> </string-array> + <string-array name="import_action_list"> + <item>@string/menu_importFromFile</item> + <item>@string/menu_keyServer</item> + <item>@string/menu_importFromQrCode</item> + <item>@string/menu_importFromNfc</item> + </string-array> + </resources>
\ No newline at end of file diff --git a/OpenPGP-Keychain/res/values/strings.xml b/OpenPGP-Keychain/res/values/strings.xml index 06d51b6e7..5975665e9 100644 --- a/OpenPGP-Keychain/res/values/strings.xml +++ b/OpenPGP-Keychain/res/values/strings.xml @@ -346,10 +346,10 @@ <string name="help_tab_about">About</string> <string name="help_about_version">Version:</string> - <!-- Import from QR Code --> - <string name="import_from_qr_code_import">Import key(s) (only locally)</string> - <string name="import_from_qr_code_import_sign_and_upload">Import, Sign, and upload key(s)</string> - <string name="import_from_qr_code_finish">Finish</string> + <!-- Import --> + <string name="import_import">Import key(s) (only locally)</string> + <string name="import_sign_and_upload">Import, Sign, and upload key(s)</string> + <string name="import_finish">Finish</string> <!-- Intent labels --> <string name="intent_decrypt_file">OpenPGP: Decrypt File</string> diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/FileHelper.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/FileHelper.java index 115e0e36d..acb7f71f8 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/FileHelper.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/helper/FileHelper.java @@ -28,6 +28,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Environment; +import android.support.v4.app.Fragment; import android.widget.Toast; public class FileHelper { @@ -55,18 +56,14 @@ public class FileHelper { * @param activity * @param filename * default selected file, not supported by all file managers - * @param type + * @param mimeType * can be text/plain for example * @param requestCode * requestCode used to identify the result coming back from file manager to * onActivityResult() in your activity */ - public static void openFile(Activity activity, String filename, String type, int requestCode) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - - intent.setData(Uri.parse("file://" + filename)); - intent.setType(type); + public static void openFile(Activity activity, String filename, String mimeType, int requestCode) { + Intent intent = buildFileIntent(filename, mimeType); try { activity.startActivityForResult(intent, requestCode); @@ -76,6 +73,28 @@ public class FileHelper { } } + public static void openFile(Fragment fragment, String filename, String mimeType, int requestCode) { + Intent intent = buildFileIntent(filename, mimeType); + + try { + fragment.startActivityForResult(intent, requestCode); + } catch (ActivityNotFoundException e) { + // No compatible file manager was found. + Toast.makeText(fragment.getActivity(), R.string.noFilemanagerInstalled, + Toast.LENGTH_SHORT).show(); + } + } + + private static Intent buildFileIntent(String filename, String mimeType) { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + + intent.setData(Uri.parse("file://" + filename)); + intent.setType(mimeType); + + return intent; + } + /** * Get a file path from a Uri. * diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportFileFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportFileFragment.java new file mode 100644 index 000000000..099a2dac1 --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportFileFragment.java @@ -0,0 +1,122 @@ +/* + * 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; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.FileHelper; +import org.sufficientlysecure.keychain.util.Log; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.ImageButton; + +public class ImportFileFragment extends Fragment { + public static final String ARG_PATH = "path"; + + private ImportKeysActivity mImportActivity; + private EditText mFilename; + private ImageButton mBrowse; + + /** + * Creates new instance of this fragment + */ + public static ImportFileFragment newInstance(String path) { + ImportFileFragment frag = new ImportFileFragment(); + + Bundle args = new Bundle(); + args.putString(ARG_PATH, path); + + frag.setArguments(args); + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false); + + mFilename = (EditText) view.findViewById(R.id.import_keys_file_input); + mBrowse = (ImageButton) view.findViewById(R.id.import_keys_file_browse); + + mBrowse.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + // open .asc or .gpg files + // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc + // or gpg types! + FileHelper.openFile(ImportFileFragment.this, mFilename.getText().toString(), "*/*", + Id.request.filename); + } + }); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mImportActivity = (ImportKeysActivity) getActivity(); + + // set default path + String path = Constants.path.APP_DIR + "/"; + if (getArguments() != null) { + path = getArguments().getString(ARG_PATH); + } + mFilename.setText(path); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.filename: { + if (resultCode == Activity.RESULT_OK && data != null) { + try { + String path = data.getData().getPath(); + Log.d(Constants.TAG, "path=" + path); + + // set filename to edittext + mFilename.setText(path); + + // load data + mImportActivity.loadCallback(null, path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); + } + } + + break; + } + + default: + super.onActivityResult(requestCode, resultCode, data); + + break; + } + } + +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeyServerFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeyServerFragment.java new file mode 100644 index 000000000..7f33ee0c6 --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeyServerFragment.java @@ -0,0 +1,51 @@ +/* + * 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; + +import org.sufficientlysecure.keychain.R; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class ImportKeyServerFragment extends Fragment { + + /** + * Creates new instance of this fragment + */ + public static ImportKeyServerFragment newInstance() { + ImportKeyServerFragment frag = new ImportKeyServerFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.import_keys_keyserver_fragment, container, false); + } + + +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index a52d2b435..8ca8080bb 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; @@ -30,30 +29,31 @@ import org.sufficientlysecure.keychain.util.Log; import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.Context; 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 android.support.v4.app.FragmentManager; +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; 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 class ImportKeysActivity extends SherlockFragmentActivity implements OnNavigationListener { public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY"; public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_QR_CODE"; // Actions for internal use only: - public static final String ACTION_IMPOR_KEY_FROM_FILE = Constants.INTENT_PREFIX + public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_FILE"; public static final String ACTION_IMPORT_KEY_FROM_NFC = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_NFC"; @@ -64,12 +64,12 @@ public class ImportKeysActivity extends SherlockFragmentActivity { // TODO: import keys from server // public static final String EXTRA_KEY_ID = "keyId"; - protected String mImportFilename; - protected byte[] mImportData; - protected boolean mDeleteAfterImport = false; FileDialogFragment mFileDialog; + ImportKeysListFragment mListFragment; + OnNavigationListener mOnNavigationListener; + String[] mNavigationStrings; @Override protected void onCreate(Bundle savedInstanceState) { @@ -80,9 +80,78 @@ public class ImportKeysActivity extends SherlockFragmentActivity { // set actionbar without home button if called from another app ActionBarHelper.setBackButton(this); + // set drop down navigation + mNavigationStrings = getResources().getStringArray(R.array.import_action_list); + Context context = getSupportActionBar().getThemedContext(); + ArrayAdapter<CharSequence> list = ArrayAdapter.createFromResource(context, + R.array.import_action_list, R.layout.sherlock_spinner_item); + list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item); + getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); + getSupportActionBar().setListNavigationCallbacks(list, this); + getSupportActionBar().setDisplayShowTitleEnabled(false); + + // Check that the activity is using the layout version with + // the fragment_container FrameLayout + if (findViewById(R.id.import_keys_list_container) != null) { + + // 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 + mListFragment = ImportKeysListFragment.newInstance(); + + // Add the fragment to the 'fragment_container' FrameLayout + getSupportFragmentManager().beginTransaction() + .replace(R.id.import_keys_list_container, mListFragment).commit(); + // do it immediately! + getSupportFragmentManager().executePendingTransactions(); + } + handleActions(getIntent()); } + @Override + public boolean onNavigationItemSelected(int itemPosition, long itemId) { + // Create new fragment from our own Fragment class + switch (itemPosition) { + case 0: + loadFragment(ImportFileFragment.class, null, mNavigationStrings[itemPosition]); + break; + case 1: + loadFragment(ImportKeyServerFragment.class, null, mNavigationStrings[itemPosition]); + break; + case 2: + loadFragment(ImportQrCodeFragment.class, null, mNavigationStrings[itemPosition]); + break; + case 3: + loadFragment(ImportNFCFragment.class, null, mNavigationStrings[itemPosition]); + break; + + default: + break; + } + return true; + } + + private void loadFragment(Class<?> clss, Bundle args, String tag) { + Fragment fragment = Fragment.instantiate(this, clss.getName(), args); + + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + // Replace whatever is in the fragment container with this fragment + // and give the fragment a tag name equal to the string at the position selected + ft.replace(R.id.import_navigation_fragment, fragment, tag); + // Apply changes + ft.commit(); + } + + public void loadCallback(byte[] importData, String importFilename) { + mListFragment.load(importData, importFilename); + } + /** * ActionBar menu is created based on class variables to change it at runtime * @@ -120,17 +189,17 @@ public class ImportKeysActivity extends SherlockFragmentActivity { return true; - case Id.menu.option.import_from_file: - showImportFromFileDialog(); - return true; - - case Id.menu.option.import_from_qr_code: - importFromQrCode(); - return true; + // case Id.menu.option.import_from_file: + // showImportFromFileDialog(); + // return true; - case Id.menu.option.import_from_nfc: - importFromNfc(); - return true; + // case Id.menu.option.import_from_qr_code: + // importFromQrCode(); + // return true; + // + // case Id.menu.option.import_from_nfc: + // importFromNfc(); + // return true; default: return super.onOptionsItemSelected(item); @@ -151,99 +220,42 @@ public class ImportKeysActivity extends SherlockFragmentActivity { */ if (Intent.ACTION_VIEW.equals(action)) { // Android's Action when opening file associated to Keychain (see AndroidManifest.xml) - // override action to delegate it to Keychains ACTION_IMPORT + // override action to delegate it to Keychain's ACTION_IMPORT_KEY action = ACTION_IMPORT_KEY; } /** - * APG's own Actions + * Keychain's own Actions */ if (ACTION_IMPORT_KEY.equals(action)) { if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { - mImportFilename = intent.getData().getPath(); - mImportData = null; + String importFilename = intent.getData().getPath(); + + // display selected filename + getSupportActionBar().setSelectedNavigationItem(0); + Bundle args = new Bundle(); + args.putString(ImportFileFragment.ARG_PATH, importFilename); + loadFragment(ImportFileFragment.class, args, mNavigationStrings[0]); + + // directly load data + loadCallback(null, importFilename); } else if (extras.containsKey(EXTRA_KEY_BYTES)) { - mImportData = intent.getByteArrayExtra(EXTRA_KEY_BYTES); - mImportFilename = null; + byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES); + loadCallback(importData, null); } - loadKeyListFragment(); - } else if (ACTION_IMPOR_KEY_FROM_FILE.equals(action)) { - if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { - mImportFilename = intent.getData().getPath(); - mImportData = null; - } - showImportFromFileDialog(); + // Internal actions: + } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { + getSupportActionBar().setSelectedNavigationItem(0); + loadFragment(ImportFileFragment.class, null, mNavigationStrings[0]); } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) { - importFromQrCode(); + getSupportActionBar().setSelectedNavigationItem(2); + loadFragment(ImportQrCodeFragment.class, null, mNavigationStrings[2]); } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) { - importFromNfc(); - } - } - - public void loadKeyListFragment() { - if (mImportData != null || mImportFilename != null) { - // generate list of keyrings - FragmentManager fragmentManager = getSupportFragmentManager(); - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - - ImportKeysListFragment listFragment = new ImportKeysListFragment(); - Bundle args = new Bundle(); - args.putByteArray(ImportKeysListFragment.ARG_KEYRING_BYTES, mImportData); - args.putString(ImportKeysListFragment.ARG_IMPORT_FILENAME, mImportFilename); - listFragment.setArguments(args); - // replace container in view with fragment - fragmentTransaction.replace(R.id.import_keys_list_container, listFragment); - fragmentTransaction.commit(); + getSupportActionBar().setSelectedNavigationItem(3); + loadFragment(ImportNFCFragment.class, null, mNavigationStrings[3]); } } - private void importFromQrCode() { - new IntentIntegrator(this).initiateScan(); - } - - private void importFromNfc() { - // show nfc help - Intent intent = new Intent(this, HelpActivity.class); - intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 1); - startActivityForResult(intent, 0); - } - - /** - * Show to dialog from where to import keys - */ - public void showImportFromFileDialog() { - // Message is received after file is selected - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == FileDialogFragment.MESSAGE_OKAY) { - Bundle data = message.getData(); - mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED); - - Log.d(Constants.TAG, "mImportFilename: " + mImportFilename); - Log.d(Constants.TAG, "mDeleteAfterImport: " + mDeleteAfterImport); - - loadKeyListFragment(); - } - } - }; - - // 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), Constants.path.APP_DIR + "/", - null, Id.request.filename); - - mFileDialog.show(getSupportFragmentManager(), "fileDialog"); - } - }); - } - // private void importAndSignOld(final long keyId, final String expectedFingerprint) { // if (expectedFingerprint != null && expectedFingerprint.length() > 0) { // @@ -302,25 +314,11 @@ public class ImportKeysActivity extends SherlockFragmentActivity { // } // } - 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 button clicked!"); - - importKeys(); - } - /** * Import keys with mImportData */ public void importKeys() { - if (mImportData != null || mImportFilename != null) { + if (mListFragment.getKeyBytes() != null || mListFragment.getImportFilename() != null) { Log.d(Constants.TAG, "importKeys started"); // Send all information needed to service to import key in other thread @@ -334,12 +332,13 @@ public class ImportKeysActivity extends SherlockFragmentActivity { // TODO: check for key type? // data.putInt(KeychainIntentService.IMPORT_KEY_TYPE, Id.type.secret_key); - if (mImportData != null) { + if (mListFragment.getKeyBytes() != null) { data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_BYTES); - data.putByteArray(KeychainIntentService.IMPORT_BYTES, mImportData); + data.putByteArray(KeychainIntentService.IMPORT_BYTES, mListFragment.getKeyBytes()); } else { data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_FILE); - data.putString(KeychainIntentService.IMPORT_FILENAME, mImportFilename); + data.putString(KeychainIntentService.IMPORT_FILENAME, + mListFragment.getImportFilename()); } intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -391,7 +390,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity { } else if (mDeleteAfterImport) { // everything went well, so now delete, if that was turned on DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mImportFilename); + .newInstance(mListFragment.getImportFilename()); deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); } } @@ -412,68 +411,17 @@ public class ImportKeysActivity extends SherlockFragmentActivity { } } + public void importOnClick(View view) { + importKeys(); + } + public void signAndUploadOnClick(View view) { // first, import! - importOnClick(view); + // 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(); - - mImportData = scanResult.getContents().getBytes(); - mImportFilename = null; - - // 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); - } - } - } - - @Override - protected void onResume() { - super.onResume(); - - loadKeyListFragment(); - } - } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 170b459be..1b12adb91 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -38,15 +38,37 @@ import android.widget.SimpleAdapter; public class ImportKeysListFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<List<Map<String, String>>> { - public static String ARG_KEYRING_BYTES = "bytes"; - public static String ARG_IMPORT_FILENAME = "filename"; - - byte[] mKeyringBytes; - String mImportFilename; + // public static final String ARG_IMPORT_DATA = "bytes"; + // public static final String ARG_IMPORT_FILENAME = "filename"; private Activity mActivity; private SimpleAdapter mAdapter; + private byte[] mKeyBytes; + private String mImportFilename; + + + + public byte[] getKeyBytes() { + return mKeyBytes; + } + + public String getImportFilename() { + return mImportFilename; + } + + /** + * Creates new instance of this fragment + */ + public static ImportKeysListFragment newInstance() { + ImportKeysListFragment frag = new ImportKeysListFragment(); + Bundle args = new Bundle(); + + frag.setArguments(args); + + return frag; + } + @Override public void onListItemClick(ListView listView, View view, int position, long id) { // Map<String, String> item = (Map<String, String>) listView.getItemAtPosition(position); @@ -76,8 +98,8 @@ public class ImportKeysListFragment extends SherlockListFragment implements mActivity = this.getActivity(); - mKeyringBytes = getArguments().getByteArray(ARG_KEYRING_BYTES); - mImportFilename = getArguments().getString(ARG_IMPORT_FILENAME); + // mKeyBytes = getArguments().getByteArray(ARG_IMPORT_DATA); + // mImportFilename = getArguments().getString(ARG_IMPORT_FILENAME); // register long press context menu registerForContextMenu(getListView()); @@ -102,9 +124,16 @@ public class ImportKeysListFragment extends SherlockListFragment implements getLoaderManager().initLoader(0, null, this); } + public void load(byte[] importData, String importFilename) { + mKeyBytes = importData; + mImportFilename = importFilename; + + getLoaderManager().initLoader(0, null, this); + } + @Override public Loader<List<Map<String, String>>> onCreateLoader(int id, Bundle args) { - return new ImportKeysListLoader(mActivity, mKeyringBytes, mImportFilename); + return new ImportKeysListLoader(mActivity, mKeyBytes, mImportFilename); } @Override diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportNFCFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportNFCFragment.java new file mode 100644 index 000000000..61820298f --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportNFCFragment.java @@ -0,0 +1,69 @@ +/* + * 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; + +import org.sufficientlysecure.keychain.R; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; + +public class ImportNFCFragment extends Fragment { + + private Button mButton; + + /** + * Creates new instance of this fragment + */ + public static ImportNFCFragment newInstance() { + ImportNFCFragment frag = new ImportNFCFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.import_keys_nfc_fragment, container, false); + + mButton = (Button) view.findViewById(R.id.import_nfc_button); + mButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + // show nfc help + Intent intent = new Intent(getActivity(), HelpActivity.class); + intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, 1); + startActivityForResult(intent, 0); + } + }); + + return view; + } + +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportQrCodeFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportQrCodeFragment.java new file mode 100644 index 000000000..94d4a620c --- /dev/null +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/ImportQrCodeFragment.java @@ -0,0 +1,116 @@ +/* + * 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; + +import org.sufficientlysecure.keychain.R; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; + +import com.google.zxing.integration.android.IntentIntegrator; +import com.google.zxing.integration.android.IntentIntegratorSupportV4; +import com.google.zxing.integration.android.IntentResult; + +public class ImportQrCodeFragment extends Fragment { + + private ImportKeysActivity mImportActivity; + private Button mButton; + + /** + * Creates new instance of this fragment + */ + public static ImportQrCodeFragment newInstance() { + ImportQrCodeFragment frag = new ImportQrCodeFragment(); + + Bundle args = new Bundle(); + frag.setArguments(args); + + return frag; + } + + /** + * Inflate the layout for this fragment + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.import_keys_qr_code_fragment, container, false); + + mButton = (Button) view.findViewById(R.id.import_qrcode_button); + mButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + // scan using xzing's Barcode Scanner + new IntentIntegratorSupportV4(ImportQrCodeFragment.this).initiateScan(); + } + }); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mImportActivity = (ImportKeysActivity) getActivity(); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case IntentIntegrator.REQUEST_CODE: { + IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, + data); + if (scanResult != null && scanResult.getFormatName() != null) { + + // mScannedContent = scanResult.getContents(); + + mImportActivity.loadCallback(scanResult.getContents().getBytes(), null); + + // mImportData = scanResult.getContents().getBytes(); + // mImportFilename = null; + + // 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); + + break; + } + } + +} diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java index c0a2f12ff..b76945811 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java @@ -154,7 +154,7 @@ public class KeyListActivity extends SherlockFragmentActivity { case Id.menu.option.import_from_file: { Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class); - intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPOR_KEY_FROM_FILE); + intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE); startActivityForResult(intentImportFromFile, 0); return true; } diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java index ed6c74b78..275842019 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicActivity.java @@ -67,7 +67,7 @@ public class KeyListPublicActivity extends KeyListActivity { } case Id.menu.option.import_from_file: { Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class); - intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPOR_KEY_FROM_FILE); + intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE); startActivityForResult(intentImportFromFile, 0); return true; diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java index 64a9e6eb1..fe7199cc0 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java @@ -42,6 +42,7 @@ import android.widget.ListView; public class SelectPublicKeyFragment extends ListFragmentWorkaround implements LoaderManager.LoaderCallbacks<Cursor> { + public static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids"; private Activity mActivity; private SelectKeyCursorAdapter mAdapter; @@ -49,8 +50,6 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements private long mSelectedMasterKeyIds[]; - private static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids"; - /** * Creates new instance of this fragment */ diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java index 47aea82e7..730fcc520 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java @@ -38,6 +38,8 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; +// TODO: return result from file manager activity to this dialog! not the activity! +// do it like in ImportFileFragment! public class FileDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; private static final String ARG_TITLE = "title"; @@ -107,7 +109,8 @@ public class FileDialogFragment extends DialogFragment { mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // only .asc or .gpg files - FileHelper.openFile(activity, mFilename.getText().toString(), "text/plain", + // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc or gpg types! + FileHelper.openFile(activity, mFilename.getText().toString(), "*/*", requestCode); } }); diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java index 45f23d443..b10e5fd26 100644 --- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java +++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/widget/ImportKeysListLoader.java @@ -65,13 +65,15 @@ public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, Strin InputData inputData = null; if (mKeyringBytes != null) { inputData = new InputData(new ByteArrayInputStream(mKeyringBytes), mKeyringBytes.length); - } else { + } else if (mImportFilename != null) { try { inputData = new InputData(new FileInputStream(mImportFilename), mImportFilename.length()); } catch (FileNotFoundException e) { Log.e(Constants.TAG, "Failed to init FileInputStream!", e); } + } else { + return data; } generateListOfKeyrings(inputData); |