This commit is contained in:
Ashley Hughes 2014-02-01 17:29:23 +00:00
commit 1e565ef872
11 changed files with 326 additions and 212 deletions

View File

@ -652,12 +652,18 @@ public class KeychainIntentService extends IntentService implements ProgressDial
break; break;
case TARGET_FILE: /* import key from file */ case TARGET_FILE: /* import key from file */
String inputFile = data.getString(IMPORT_FILENAME); // dataUri!
inStream = new FileInputStream(inputFile); try {
File file = new File(inputFile); inStream = getContentResolver().openInputStream(dataUri);
inLength = file.length(); inLength = inStream.available();
inputData = new InputData(inStream, inLength);
inputData = new InputData(inStream, inLength);
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "FileNotFoundException!", e);
} catch (IOException e) {
Log.e(Constants.TAG, "IOException!", e);
}
break; break;

View File

@ -23,11 +23,10 @@ import java.util.Locale;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; 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 org.sufficientlysecure.keychain.util.Log;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@ -72,8 +71,9 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
// only used by ACTION_IMPORT_KEY_FROM_KEYSERVER // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER
public static final String EXTRA_QUERY = "query"; public static final String EXTRA_QUERY = "query";
public static final String EXTRA_KEY_ID = "key_id";
protected boolean mDeleteAfterImport = false; public static final String EXTRA_FINGERPRINT = "fingerprint";
// public static final String RESULT_EXTRA_TEXT = "text";
// view // view
private ImportKeysListFragment mListFragment; private ImportKeysListFragment mListFragment;
@ -143,17 +143,12 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
* Keychain's own Actions * Keychain's own Actions
*/ */
if (ACTION_IMPORT_KEY.equals(action)) { if (ACTION_IMPORT_KEY.equals(action)) {
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { getSupportActionBar().setSelectedNavigationItem(1);
String importFilename = intent.getData().getPath(); loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]);
// display selected filename
getSupportActionBar().setSelectedNavigationItem(1);
Bundle args = new Bundle();
args.putString(ImportKeysFileFragment.ARG_PATH, importFilename);
loadFragment(ImportKeysFileFragment.class, args, mNavigationStrings[1]);
if (dataUri != null) {
// directly load data // directly load data
startListFragment(savedInstanceState, null, importFilename); startListFragment(savedInstanceState, null, dataUri);
} else if (extras.containsKey(EXTRA_KEY_BYTES)) { } else if (extras.containsKey(EXTRA_KEY_BYTES)) {
byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES); byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES);
@ -161,12 +156,29 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
startListFragment(savedInstanceState, importData, null); startListFragment(savedInstanceState, importData, null);
} }
} else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) { } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) {
if (!extras.containsKey(EXTRA_QUERY)) { String query = null;
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query' extra!"); if (extras.containsKey(EXTRA_QUERY)) {
query = extras.getString(EXTRA_QUERY);
} else if (extras.containsKey(EXTRA_KEY_ID)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
if (keyId != 0) {
query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
}
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
if (fingerprint != null) {
query = "0x" + fingerprint;
}
} else {
Log.e(Constants.TAG, "IMPORT_KEY_FROM_KEYSERVER action needs to contain the 'query', 'key_id', or 'fingerprint' extra!");
return; return;
} }
String query = extras.getString(EXTRA_QUERY); // search directly
getSupportActionBar().setSelectedNavigationItem(0);
Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]);
// TODO: implement KEYSERVER! // TODO: implement KEYSERVER!
@ -188,7 +200,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
} }
} }
private void startListFragment(Bundle savedInstanceState, byte[] bytes, String filename) { private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri) {
// Check that the activity is using the layout version with // Check that the activity is using the layout version with
// the fragment_container FrameLayout // the fragment_container FrameLayout
if (findViewById(R.id.import_keys_list_container) != null) { if (findViewById(R.id.import_keys_list_container) != null) {
@ -201,7 +213,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
} }
// Create an instance of the fragment // Create an instance of the fragment
mListFragment = ImportKeysListFragment.newInstance(bytes, filename); mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, null);
// Add the fragment to the 'fragment_container' FrameLayout // Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes! // NOTE: We use commitAllowingStateLoss() to prevent weird crashes!
@ -217,24 +229,24 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
public boolean onNavigationItemSelected(int itemPosition, long itemId) { public boolean onNavigationItemSelected(int itemPosition, long itemId) {
// Create new fragment from our own Fragment class // Create new fragment from our own Fragment class
switch (itemPosition) { switch (itemPosition) {
case 0: case 0:
loadFragment(ImportKeysServerFragment.class, null, mNavigationStrings[itemPosition]); loadFragment(ImportKeysServerFragment.class, null, mNavigationStrings[itemPosition]);
break; break;
case 1: case 1:
loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[itemPosition]); loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[itemPosition]);
break; break;
case 2: case 2:
loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]); loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]);
break; break;
case 3: case 3:
loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]); loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]);
break; break;
case 4: case 4:
loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]); loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]);
break; break;
default: default:
break; break;
} }
return true; return true;
} }
@ -267,8 +279,8 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
startActivity(queryIntent); startActivity(queryIntent);
} }
public void loadCallback(byte[] importData, String importFilename) { public void loadCallback(byte[] importData, Uri dataUri, String serverQuery) {
mListFragment.loadNew(importData, importFilename); mListFragment.loadNew(importData, dataUri, serverQuery);
} }
// private void importAndSignOld(final long keyId, final String expectedFingerprint) { // private void importAndSignOld(final long keyId, final String expectedFingerprint) {
@ -333,7 +345,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
* Import keys with mImportData * Import keys with mImportData
*/ */
public void importKeys() { public void importKeys() {
if (mListFragment.getKeyBytes() != null || mListFragment.getImportFilename() != null) { if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
Log.d(Constants.TAG, "importKeys started"); Log.d(Constants.TAG, "importKeys started");
// Send all information needed to service to import key in other thread // Send all information needed to service to import key in other thread
@ -360,8 +372,7 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
data.putByteArray(KeychainIntentService.IMPORT_BYTES, mListFragment.getKeyBytes()); data.putByteArray(KeychainIntentService.IMPORT_BYTES, mListFragment.getKeyBytes());
} else { } else {
data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_FILE); data.putInt(KeychainIntentService.TARGET, KeychainIntentService.TARGET_FILE);
data.putString(KeychainIntentService.IMPORT_FILENAME, intent.setData(mListFragment.getDataUri());
mListFragment.getImportFilename());
} }
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
@ -417,14 +428,11 @@ public class ImportKeysActivity extends DrawerActivity implements OnNavigationLi
}); });
alert.setCancelable(true); alert.setCancelable(true);
alert.create().show(); alert.create().show();
} else if (mDeleteAfterImport) {
// everything went well, so now delete, if that was turned on
DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
.newInstance(mListFragment.getImportFilename());
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
} }
} }
}; }
;
}; };
// Create a new Messenger for the communication back // Create a new Messenger for the communication back

View File

@ -62,7 +62,7 @@ public class ImportKeysClipboardFragment extends Fragment {
String sendText = ""; String sendText = "";
if (clipboardText != null) if (clipboardText != null)
sendText = clipboardText.toString(); sendText = clipboardText.toString();
mImportActivity.loadCallback(sendText.getBytes(), null); mImportActivity.loadCallback(sendText.getBytes(), null, null);
} }
}); });

View File

@ -21,7 +21,6 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.FileHelper;
import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
@ -30,25 +29,20 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.EditText;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
public class ImportKeysFileFragment extends Fragment { public class ImportKeysFileFragment extends Fragment {
public static final String ARG_PATH = "path";
private ImportKeysActivity mImportActivity; private ImportKeysActivity mImportActivity;
private EditText mFilename;
private BootstrapButton mBrowse; private BootstrapButton mBrowse;
/** /**
* Creates new instance of this fragment * Creates new instance of this fragment
*/ */
public static ImportKeysFileFragment newInstance(String path) { public static ImportKeysFileFragment newInstance() {
ImportKeysFileFragment frag = new ImportKeysFileFragment(); ImportKeysFileFragment frag = new ImportKeysFileFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ARG_PATH, path);
frag.setArguments(args); frag.setArguments(args);
return frag; return frag;
@ -61,7 +55,6 @@ public class ImportKeysFileFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false); View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
mFilename = (EditText) view.findViewById(R.id.import_keys_file_input);
mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse); mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse);
mBrowse.setOnClickListener(new View.OnClickListener() { mBrowse.setOnClickListener(new View.OnClickListener() {
@ -69,7 +62,7 @@ public class ImportKeysFileFragment extends Fragment {
// open .asc or .gpg files // open .asc or .gpg files
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
// or gpg types! // or gpg types!
FileHelper.openFile(ImportKeysFileFragment.this, mFilename.getText().toString(), FileHelper.openFile(ImportKeysFileFragment.this, Constants.path.APP_DIR + "/",
"*/*", Id.request.filename); "*/*", Id.request.filename);
} }
}); });
@ -82,42 +75,25 @@ public class ImportKeysFileFragment extends Fragment {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
mImportActivity = (ImportKeysActivity) getActivity(); mImportActivity = (ImportKeysActivity) getActivity();
// set default path
String path = Constants.path.APP_DIR + "/";
if (getArguments() != null && getArguments().containsKey(ARG_PATH)) {
path = getArguments().getString(ARG_PATH);
}
mFilename.setText(path);
} }
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode & 0xFFFF) { switch (requestCode & 0xFFFF) {
case Id.request.filename: { case Id.request.filename: {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
String path = null;
try {
path = data.getData().getPath();
Log.d(Constants.TAG, "path=" + path);
// set filename to edittext // load data
mFilename.setText(path); mImportActivity.loadCallback(null, data.getData(), null);
} catch (NullPointerException e) {
Log.e(Constants.TAG, "Nullpointer while retrieving path!", e);
} }
// load data break;
mImportActivity.loadCallback(null, path);
} }
break; default:
} super.onActivityResult(requestCode, resultCode, data);
default: break;
super.onActivityResult(requestCode, resultCode, data);
break;
} }
} }

View File

@ -1,18 +1,18 @@
/* /*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * This program is free software: you can redistribute it and/or modify
* you may not use this file except in compliance with the License. * it under the terms of the GNU General Public License as published by
* You may obtain a copy of the License at * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* http://www.apache.org/licenses/LICENSE-2.0 * 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.
* *
* Unless required by applicable law or agreed to in writing, software * You should have received a copy of the GNU General Public License
* distributed under the License is distributed on an "AS IS" BASIS, * along with this program. If not, see <http://www.gnu.org/licenses/>.
* 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; package org.sufficientlysecure.keychain.ui;
@ -20,6 +20,8 @@ package org.sufficientlysecure.keychain.ui;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List; import java.util.List;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@ -31,6 +33,7 @@ import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import android.app.Activity; import android.app.Activity;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
@ -41,21 +44,26 @@ import com.actionbarsherlock.app.SherlockListFragment;
public class ImportKeysListFragment extends SherlockListFragment implements public class ImportKeysListFragment extends SherlockListFragment implements
LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> { LoaderManager.LoaderCallbacks<List<ImportKeysListEntry>> {
private static final String ARG_FILENAME = "filename"; private static final String ARG_DATA_URI = "uri";
private static final String ARG_BYTES = "bytes"; private static final String ARG_BYTES = "bytes";
private static final String ARG_SERVER_QUERY = "query";
private Activity mActivity; private Activity mActivity;
private ImportKeysAdapter mAdapter; private ImportKeysAdapter mAdapter;
private byte[] mKeyBytes; private byte[] mKeyBytes;
private String mImportFilename; private Uri mDataUri;
private String mServerQuery;
private static final int LOADER_ID_BYTES = 0;
private static final int LOADER_ID_SERVER_QUERY = 1;
public byte[] getKeyBytes() { public byte[] getKeyBytes() {
return mKeyBytes; return mKeyBytes;
} }
public String getImportFilename() { public Uri getDataUri() {
return mImportFilename; return mDataUri;
} }
public List<ImportKeysListEntry> getData() { public List<ImportKeysListEntry> getData() {
@ -65,12 +73,13 @@ public class ImportKeysListFragment extends SherlockListFragment implements
/** /**
* Creates new instance of this fragment * Creates new instance of this fragment
*/ */
public static ImportKeysListFragment newInstance(byte[] bytes, String filename) { public static ImportKeysListFragment newInstance(byte[] bytes, Uri dataUri, String serverQuery) {
ImportKeysListFragment frag = new ImportKeysListFragment(); ImportKeysListFragment frag = new ImportKeysListFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putByteArray(ARG_BYTES, bytes); args.putByteArray(ARG_BYTES, bytes);
args.putString(ARG_FILENAME, filename); args.putParcelable(ARG_DATA_URI, dataUri);
args.putString(ARG_SERVER_QUERY, serverQuery);
frag.setArguments(args); frag.setArguments(args);
@ -87,8 +96,9 @@ public class ImportKeysListFragment extends SherlockListFragment implements
mActivity = getActivity(); mActivity = getActivity();
if (getArguments() != null) { if (getArguments() != null) {
mImportFilename = getArguments().getString(ARG_FILENAME); mDataUri = getArguments().getParcelable(ARG_DATA_URI);
mKeyBytes = getArguments().getByteArray(ARG_BYTES); mKeyBytes = getArguments().getByteArray(ARG_BYTES);
mServerQuery = getArguments().getString(ARG_SERVER_QUERY);
} }
// Give some text to display if there is no data. In a real // Give some text to display if there is no data. In a real
@ -105,7 +115,8 @@ public class ImportKeysListFragment extends SherlockListFragment implements
// Prepare the loader. Either re-connect with an existing one, // Prepare the loader. Either re-connect with an existing one,
// or start a new one. // or start a new one.
// give arguments to onCreateLoader() // give arguments to onCreateLoader()
getLoaderManager().initLoader(0, null, this); getLoaderManager().initLoader(LOADER_ID_BYTES, null, this);
getLoaderManager().initLoader(LOADER_ID_SERVER_QUERY, null, this);
} }
@Override @Override
@ -120,58 +131,101 @@ public class ImportKeysListFragment extends SherlockListFragment implements
mAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
} }
public void loadNew(byte[] importData, String importFilename) { public void loadNew(byte[] importData, Uri dataUri, String serverQuery) {
this.mKeyBytes = importData; mKeyBytes = importData;
this.mImportFilename = importFilename; mDataUri = dataUri;
mServerQuery = serverQuery;
getLoaderManager().restartLoader(0, null, this); if (mKeyBytes != null || mDataUri != null)
getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this);
if (mServerQuery != null)
getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this);
} }
@Override @Override
public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) { public Loader<List<ImportKeysListEntry>> onCreateLoader(int id, Bundle args) {
InputData inputData = getInputData(mKeyBytes, mImportFilename); switch (id) {
return new ImportKeysListLoader(mActivity, inputData); case LOADER_ID_BYTES: {
InputData inputData = getInputData(mKeyBytes, mDataUri);
return new ImportKeysListLoader(mActivity, inputData);
}
case LOADER_ID_SERVER_QUERY: {
}
default:
return null;
}
} }
private InputData getInputData(byte[] importBytes, String importFilename) { @Override
public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
List<ImportKeysListEntry> data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
switch (loader.getId()) {
case LOADER_ID_BYTES:
Log.d(Constants.TAG, "data: " + data);
// swap in the real data!
mAdapter.setData(data);
mAdapter.notifyDataSetChanged();
setListAdapter(mAdapter);
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
break;
case LOADER_ID_SERVER_QUERY:
break;
default:
break;
}
}
@Override
public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
switch (loader.getId()) {
case LOADER_ID_BYTES:
// Clear the data in the adapter.
mAdapter.clear();
break;
case LOADER_ID_SERVER_QUERY:
// Clear the data in the adapter.
mAdapter.clear();
break;
default:
break;
}
}
private InputData getInputData(byte[] importBytes, Uri dataUri) {
InputData inputData = null; InputData inputData = null;
if (importBytes != null) { if (importBytes != null) {
inputData = new InputData(new ByteArrayInputStream(importBytes), importBytes.length); inputData = new InputData(new ByteArrayInputStream(importBytes), importBytes.length);
} else if (importFilename != null) { } else if (dataUri != null) {
try { try {
inputData = new InputData(new FileInputStream(importFilename), InputStream inputStream = getActivity().getContentResolver().openInputStream(dataUri);
importFilename.length()); int length = inputStream.available();
inputData = new InputData(inputStream, length);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.e(Constants.TAG, "Failed to init FileInputStream!", e); Log.e(Constants.TAG, "FileNotFoundException!", e);
} catch (IOException e) {
Log.e(Constants.TAG, "IOException!", e);
} }
} }
return inputData; return inputData;
} }
@Override
public void onLoadFinished(Loader<List<ImportKeysListEntry>> loader,
List<ImportKeysListEntry> data) {
Log.d(Constants.TAG, "data: " + data);
// swap in the real data!
mAdapter.setData(data);
mAdapter.notifyDataSetChanged();
setListAdapter(mAdapter);
// The list should now be shown.
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<List<ImportKeysListEntry>> loader) {
// Clear the data in the adapter.
mAdapter.clear();
}
} }

View File

@ -190,7 +190,7 @@ public class ImportKeysQrCodeFragment extends Fragment {
for (String in : mScannedContent) { for (String in : mScannedContent) {
result += in; result += in;
} }
mImportActivity.loadCallback(result.getBytes(), null); mImportActivity.loadCallback(result.getBytes(), null, null);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -17,22 +17,36 @@
package org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
public class ImportKeysServerFragment extends Fragment { public class ImportKeysServerFragment extends Fragment {
private BootstrapButton mButton; public static final String ARG_QUERY = "query";
String mQuery; private ImportKeysActivity mImportActivity;
private BootstrapButton mOldButton;
private BootstrapButton mSearchButton;
private EditText mQueryEditText;
private Spinner mServerSpinner;
/** /**
* Creates new instance of this fragment * Creates new instance of this fragment
@ -41,6 +55,8 @@ public class ImportKeysServerFragment extends Fragment {
ImportKeysServerFragment frag = new ImportKeysServerFragment(); ImportKeysServerFragment frag = new ImportKeysServerFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ARG_QUERY, query);
frag.setArguments(args); frag.setArguments(args);
return frag; return frag;
@ -51,14 +67,52 @@ public class ImportKeysServerFragment extends Fragment {
*/ */
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_keyserver_fragment, container, false); View view = inflater.inflate(R.layout.import_keys_server_fragment, container, false);
mButton = (BootstrapButton) view.findViewById(R.id.import_keyserver_button); mSearchButton = (BootstrapButton) view.findViewById(R.id.import_server_button);
mButton.setOnClickListener(new OnClickListener() { mQueryEditText = (EditText) view.findViewById(R.id.import_server_query);
mServerSpinner = (Spinner) view.findViewById(R.id.import_server_spinner);
// add keyservers to spinner
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, Preferences.getPreferences(getActivity())
.getKeyServers());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mServerSpinner.setAdapter(adapter);
if (adapter.getCount() > 0) {
mServerSpinner.setSelection(0);
} else {
mSearchButton.setEnabled(false);
}
mSearchButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String query = mQueryEditText.getText().toString();
}
});
// TODO: not supported by BootstrapButton
// mSearchButton.setOnEditorActionListener(new TextView.OnEditorActionListener() {
// @Override
// public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// if (actionId == EditorInfo.IME_ACTION_SEARCH) {
// String query = mQueryEditText.getText().toString();
// search(query);
// // FIXME This is a hack to hide a keyboard after search
// // http://tinyurl.com/pwdc3q9
// return false;
// }
// return false;
// }
// });
// TODO: remove:
mOldButton = (BootstrapButton) view.findViewById(R.id.import_server_button);
mOldButton.setOnClickListener(new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
// TODO: use fragment instead of activity, handle onresult here!
startActivityForResult(new Intent(getActivity(), KeyServerQueryActivity.class), 0); startActivityForResult(new Intent(getActivity(), KeyServerQueryActivity.class), 0);
} }
}); });
@ -66,4 +120,22 @@ public class ImportKeysServerFragment extends Fragment {
return view; return view;
} }
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mImportActivity = (ImportKeysActivity) getActivity();
// if query has been set on instantiation, search immediately!
if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) {
String query = getArguments().getString(ARG_QUERY);
mQueryEditText.setText(query);
search(query);
}
}
private void search(String query) {
}
} }

View File

@ -330,7 +330,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
creationDate)); creationDate));
} }
// get creation date from EXPIRY // get expiry date from EXPIRY
if (data.isNull(KEYS_INDEX_EXPIRY)) { if (data.isNull(KEYS_INDEX_EXPIRY)) {
mExpiry.setText(R.string.none); mExpiry.setText(R.string.none);
} else { } else {
@ -346,7 +346,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements
byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT); byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
if (fingerprintBlob == null) { if (fingerprintBlob == null) {
// FALLBACK for old databases // FALLBACK for old database entries
fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
} }
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);

View File

@ -3,29 +3,16 @@
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:orientation="vertical">
<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" />
<com.beardedhen.androidbootstrap.BootstrapButton <com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_keys_file_browse" android:id="@+id/import_keys_file_browse"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="70dp"
android:layout_gravity="center_vertical" android:layout_margin="10dp"
android:layout_margin="4dp" android:text="@string/filemanager_title_open"
android:contentDescription="@string/filemanager_title_open" android:contentDescription="@string/filemanager_title_open"
bootstrapbutton:bb_icon_left="fa-folder-open" bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default" bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" /> bootstrapbutton:bb_type="default" />

View File

@ -1,43 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_keyserver_button"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_margin="10dp"
android:text="@string/menu_key_server"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
<!-- <Spinner -->
<!-- android:id="@+id/import_keys_server_key_server" -->
<!-- android:layout_width="fill_parent" -->
<!-- android:layout_height="wrap_content" /> -->
<!-- <LinearLayout -->
<!-- android:layout_width="fill_parent" -->
<!-- android:layout_height="wrap_content" -->
<!-- android:orientation="horizontal" > -->
<!-- <EditText -->
<!-- android:id="@+id/import_keys_server_query" -->
<!-- android:layout_width="0dip" -->
<!-- android:layout_height="wrap_content" -->
<!-- android:layout_weight="1" -->
<!-- android:inputType="textPersonName|textEmailAddress" /> -->
<!-- <Button -->
<!-- android:id="@+id/import_keys_server_search" -->
<!-- android:layout_width="wrap_content" -->
<!-- android:layout_height="wrap_content" -->
<!-- android:text="@string/btn_search" /> -->
<!-- </LinearLayout> -->
</LinearLayout>

View File

@ -0,0 +1,54 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<Spinner
android:id="@+id/import_server_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/import_server_query"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top|left"
android:hint="@string/hint_public_keys"
android:imeOptions="actionSearch"
android:inputType="textNoSuggestions"
android:singleLine="true"
android:lines="1"
android:maxLines="1"
android:minLines="1"
android:layout_gravity="center_vertical" />
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_server_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
bootstrapbutton:bb_icon_left="fa-search"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_server_button"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_margin="10dp"
android:text="@string/menu_key_server"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>