Merge remote-tracking branch 'origin/master' into certs

Conflicts:
	OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
This commit is contained in:
Vincent Breitmoser 2014-04-06 04:35:05 +02:00
commit d1b0d0fa5e
22 changed files with 130 additions and 195 deletions

View File

@ -107,12 +107,12 @@
android:name=".ui.SelectPublicKeyActivity" android:name=".ui.SelectPublicKeyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_select_recipients" android:label="@string/title_select_recipients"
android:launchMode="singleTop"></activity> android:launchMode="singleTop" />
<activity <activity
android:name=".ui.SelectSecretKeyActivity" android:name=".ui.SelectSecretKeyActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_select_secret_key" android:label="@string/title_select_secret_key"
android:launchMode="singleTop"></activity> android:launchMode="singleTop" />
<activity <activity
android:name=".ui.EncryptActivity" android:name=".ui.EncryptActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
@ -370,6 +370,9 @@
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.KeyListActivity" />
</activity> </activity>
<activity <activity
android:name=".ui.HelpActivity" android:name=".ui.HelpActivity"

View File

@ -48,8 +48,7 @@ public final class Constants {
public static final class Path { public static final class Path {
public static final String APP_DIR = Environment.getExternalStorageDirectory() public static final String APP_DIR = Environment.getExternalStorageDirectory()
+ "/OpenKeychain"; + "/OpenKeychain";
public static final String APP_DIR_FILE_SEC = APP_DIR + "/secexport.asc"; public static final String APP_DIR_FILE = APP_DIR + "/export.asc";
public static final String APP_DIR_FILE_PUB = APP_DIR + "/pubexport.asc";
} }
public static final class Pref { public static final class Pref {
@ -72,13 +71,11 @@ public final class Constants {
public static final Class KEY_LIST = KeyListActivity.class; public static final Class KEY_LIST = KeyListActivity.class;
public static final Class ENCRYPT = EncryptActivity.class; public static final Class ENCRYPT = EncryptActivity.class;
public static final Class DECRYPT = DecryptActivity.class; public static final Class DECRYPT = DecryptActivity.class;
public static final Class IMPORT_KEYS = ImportKeysActivity.class;
public static final Class REGISTERED_APPS_LIST = AppsListActivity.class; public static final Class REGISTERED_APPS_LIST = AppsListActivity.class;
public static final Class[] ARRAY = new Class[]{ public static final Class[] ARRAY = new Class[]{
KEY_LIST, KEY_LIST,
ENCRYPT, ENCRYPT,
DECRYPT, DECRYPT,
IMPORT_KEYS,
REGISTERED_APPS_LIST REGISTERED_APPS_LIST
}; };
} }

View File

@ -43,8 +43,8 @@ import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
@ -77,6 +77,7 @@ public class ProviderHelper {
public static Object getGenericData(Context context, Uri uri, String column, int type) { public static Object getGenericData(Context context, Uri uri, String column, int type) {
return getGenericData(context, uri, new String[] { column }, new int[] { type }).get(column); return getGenericData(context, uri, new String[] { column }, new int[] { type }).get(column);
} }
public static HashMap<String,Object> getGenericData(Context context, Uri uri, String[] proj, int[] types) { public static HashMap<String,Object> getGenericData(Context context, Uri uri, String[] proj, int[] types) {
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
@ -105,10 +106,15 @@ public class ProviderHelper {
public static Object getUnifiedData(Context context, long masterKeyId, String column, int type) { public static Object getUnifiedData(Context context, long masterKeyId, String column, int type) {
return getUnifiedData(context, masterKeyId, new String[] { column }, new int[] { type }).get(column); return getUnifiedData(context, masterKeyId, new String[] { column }, new int[] { type }).get(column);
} }
public static HashMap<String,Object> getUnifiedData(Context context, long masterKeyId, String[] proj, int[] types) { public static HashMap<String,Object> getUnifiedData(Context context, long masterKeyId, String[] proj, int[] types) {
return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj, types); return getGenericData(context, KeyRings.buildUnifiedKeyRingUri(Long.toString(masterKeyId)), proj, types);
} }
/**
* Find the master key id related to a given query. The id will either be extracted from the
* query, which should work for all specific /key_rings/ queries, or will be queried if it can't.
*/
public static long getMasterKeyId(Context context, Uri queryUri) { public static long getMasterKeyId(Context context, Uri queryUri) {
// try extracting from the uri first // try extracting from the uri first
String firstSegment = queryUri.getPathSegments().get(1); String firstSegment = queryUri.getPathSegments().get(1);
@ -504,6 +510,7 @@ public class ProviderHelper {
return null; return null;
} }
} }
private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) { private static Cursor getCursorWithSelectedKeyringMasterKeyIds(Context context, long[] masterKeyIds) {
Cursor cursor = null; Cursor cursor = null;
if (masterKeyIds != null && masterKeyIds.length > 0) { if (masterKeyIds != null && masterKeyIds.length > 0) {

View File

@ -81,7 +81,6 @@ public class DrawerActivity extends ActionBarActivity {
new NavItem("fa-user", getString(R.string.nav_contacts)), new NavItem("fa-user", getString(R.string.nav_contacts)),
new NavItem("fa-lock", getString(R.string.nav_encrypt)), new NavItem("fa-lock", getString(R.string.nav_encrypt)),
new NavItem("fa-unlock", getString(R.string.nav_decrypt)), new NavItem("fa-unlock", getString(R.string.nav_decrypt)),
new NavItem("fa-download", getString(R.string.nav_import)),
new NavItem("fa-android", getString(R.string.nav_apps))}; new NavItem("fa-android", getString(R.string.nav_apps))};
mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item, mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item,
@ -264,7 +263,7 @@ public class DrawerActivity extends ActionBarActivity {
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView; View row = convertView;
NavItemHolder holder = null; NavItemHolder holder;
if (row == null) { if (row == null) {
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();

View File

@ -31,8 +31,6 @@ import android.os.Messenger;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
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;
@ -40,29 +38,26 @@ import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
import com.devspark.appmsg.AppMsg; import com.devspark.appmsg.AppMsg;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.sufficientlysecure.keychain.Constants; 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.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
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.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
import org.sufficientlysecure.keychain.ui.widget.Editor; import org.sufficientlysecure.keychain.ui.widget.Editor;
@ -142,9 +137,24 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
mExportHelper = new ExportHelper(this); mExportHelper = new ExportHelper(this);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); // Inflate a "Done"/"Cancel" custom action bar view
getSupportActionBar().setIcon(android.R.color.transparent); ActionBarHelper.setTwoButtonView(getSupportActionBar(),
getSupportActionBar().setHomeButtonEnabled(true); R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Save
saveClicked();
}
}, R.string.menu_key_edit_cancel, R.drawable.ic_action_cancel,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Cancel
cancelClicked();
}
}
);
mUserIds = new Vector<String>(); mUserIds = new Vector<String>();
mKeys = new Vector<PGPSecretKey>(); mKeys = new Vector<PGPSecretKey>();
@ -281,62 +291,6 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
} }
} }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.key_edit, menu);
//totally get rid of some actions for new keys
if (mDataUri == null) {
MenuItem mButton = menu.findItem(R.id.menu_key_edit_export_file);
mButton.setVisible(false);
mButton = menu.findItem(R.id.menu_key_edit_delete);
mButton.setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
cancelClicked();
// TODO: why isn't this triggered on my tablet - one of many ui problems
// I've had with this device. A code compatibility issue or a Samsung fail?
return true;
case R.id.menu_key_edit_cancel:
cancelClicked();
return true;
case R.id.menu_key_edit_export_file:
if (needsSaving()) {
Toast.makeText(this, R.string.error_save_first, Toast.LENGTH_LONG).show();
} else {
long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
mExportHelper.showExportKeysDialog(
new long[] { masterKeyId }, Constants.Path.APP_DIR_FILE_SEC, true);
return true;
}
return true;
case R.id.menu_key_edit_delete:
Uri convertUri = KeyRingData.buildSecretKeyRingUri(mDataUri);
// Message is received after key is deleted
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
setResult(RESULT_CANCELED);
finish();
}
}};
mExportHelper.deleteKey(convertUri, returnHandler);
return true;
case R.id.menu_key_edit_save:
saveClicked();
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void finallyEdit(final long masterKeyId) { private void finallyEdit(final long masterKeyId) {
if (masterKeyId != 0) { if (masterKeyId != 0) {
@ -351,7 +305,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
} }
} else { } else {
Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId); Log.e(Constants.TAG, "Keyring not found with masterKeyId: " + masterKeyId);
Toast.makeText(this, R.string.error_no_secret_key_found, Toast.LENGTH_LONG).show(); AppMsg.makeText(this, R.string.error_no_secret_key_found, AppMsg.STYLE_ALERT).show();
// TODO // TODO
} }
if (masterKey != null) { if (masterKey != null) {
@ -540,8 +494,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
checkEmptyIDsWanted(); checkEmptyIDsWanted();
} }
} catch (PgpGeneralException e) { } catch (PgpGeneralException e) {
Toast.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
Toast.LENGTH_SHORT).show(); AppMsg.STYLE_ALERT).show();
} }
} else { } else {
AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show(); AppMsg.makeText(this, R.string.error_change_something_first, AppMsg.STYLE_ALERT).show();
@ -586,8 +540,7 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
} }
} catch (PgpGeneralException e) { } catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage())); Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
Toast.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.STYLE_ALERT).show();
Toast.LENGTH_SHORT).show();
} }
finallySaveClicked(); finallySaveClicked();
} }
@ -663,8 +616,8 @@ public class EditKeyActivity extends ActionBarActivity implements EditorListener
startService(intent); startService(intent);
} catch (PgpGeneralException e) { } catch (PgpGeneralException e) {
Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage())); Log.e(Constants.TAG, getString(R.string.error_message, e.getMessage()));
Toast.makeText(this, getString(R.string.error_message, e.getMessage()), AppMsg.makeText(this, getString(R.string.error_message, e.getMessage()),
Toast.LENGTH_SHORT).show(); AppMsg.STYLE_ALERT).show();
} }
} }

View File

@ -190,21 +190,20 @@ public class EncryptAsymmetricFragment extends Fragment {
mMainUserId.setText(""); mMainUserId.setText("");
mMainUserIdRest.setText(""); mMainUserIdRest.setText("");
} else { } else {
String uid = getResources().getString(R.string.user_id_no_name);
String uidExtra = "";
// See if we can get a user_id from a unified query // See if we can get a user_id from a unified query
String user_id = (String) ProviderHelper.getUnifiedData( String userIdResult = (String) ProviderHelper.getUnifiedData(
getActivity(), mSecretKeyId, KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING); getActivity(), mSecretKeyId, KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING);
if(user_id != null) { String[] userId = PgpKeyHelper.splitUserId(userIdResult);
String chunks[] = user_id.split(" <", 2); if (userId[0] != null) {
uid = chunks[0]; mMainUserId.setText(userId[0]);
if (chunks.length > 1) { } else {
uidExtra = "<" + chunks[1]; mMainUserId.setText(getResources().getString(R.string.user_id_no_name));
} }
if (userId[1] != null) {
mMainUserIdRest.setText(userId[1]);
} else {
mMainUserIdRest.setText("");
} }
mMainUserId.setText(uid);
mMainUserIdRest.setText(uidExtra);
mSign.setChecked(true); mSign.setChecked(true);
} }
} }

View File

@ -32,6 +32,7 @@ import android.os.Parcelable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@ -41,6 +42,7 @@ import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; 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;
@ -51,7 +53,7 @@ import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNavigationListener { public class ImportKeysActivity extends ActionBarActivity implements ActionBar.OnNavigationListener {
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY"; 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 public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_QR_CODE"; + "IMPORT_KEY_FROM_QR_CODE";
@ -113,10 +115,9 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) { if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
setTitle(R.string.nav_import); setTitle(R.string.nav_import);
} else { } else {
ActionBarHelper.setBackButton(this);
getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayShowTitleEnabled(false);
setupDrawerNavigation(savedInstanceState);
// set drop down navigation // set drop down navigation
Context context = getSupportActionBar().getThemedContext(); Context context = getSupportActionBar().getThemedContext();
ArrayAdapter<CharSequence> navigationAdapter = ArrayAdapter.createFromResource(context, ArrayAdapter<CharSequence> navigationAdapter = ArrayAdapter.createFromResource(context,
@ -128,7 +129,6 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
handleActions(savedInstanceState, getIntent()); handleActions(savedInstanceState, getIntent());
} }
protected void handleActions(Bundle savedInstanceState, Intent intent) { protected void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();

View File

@ -53,7 +53,7 @@ public class KeyListActivity extends DrawerActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_key_list_import: case R.id.menu_key_list_import:
callIntentForDrawerItem(Constants.DrawerItems.IMPORT_KEYS); importKeys();
return true; return true;
case R.id.menu_key_list_create: case R.id.menu_key_list_create:
@ -65,7 +65,7 @@ public class KeyListActivity extends DrawerActivity {
return true; return true;
case R.id.menu_key_list_export: case R.id.menu_key_list_export:
mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE_PUB, true); mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
return true; return true;
default: default:
@ -73,6 +73,11 @@ public class KeyListActivity extends DrawerActivity {
} }
} }
private void importKeys() {
Intent intent = new Intent(this, ImportKeysActivity.class);
startActivityForResult(intent, 0);
}
private void createKey() { private void createKey() {
Intent intent = new Intent(this, EditKeyActivity.class); Intent intent = new Intent(this, EditKeyActivity.class);
intent.setAction(EditKeyActivity.ACTION_CREATE_KEY); intent.setAction(EditKeyActivity.ACTION_CREATE_KEY);

View File

@ -193,7 +193,7 @@ public class KeyListFragment extends Fragment
ids = mAdapter.getCurrentSelectedMasterKeyIds(); ids = mAdapter.getCurrentSelectedMasterKeyIds();
ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity());
mExportHelper.showExportKeysDialog( mExportHelper.showExportKeysDialog(
ids, Constants.Path.APP_DIR_FILE_PUB, mAdapter.isAnySecretSelected()); ids, Constants.Path.APP_DIR_FILE, mAdapter.isAnySecretSelected());
break; break;
} }
case R.id.menu_key_list_multi_select_all: { case R.id.menu_key_list_multi_select_all: {

View File

@ -31,6 +31,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.Window; import android.view.Window;
import android.widget.Toast; import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants; 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;
@ -44,6 +45,7 @@ import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
public class ViewKeyActivity extends ActionBarActivity { public class ViewKeyActivity extends ActionBarActivity {
@ -119,12 +121,7 @@ public class ViewKeyActivity extends ActionBarActivity {
uploadToKeyserver(mDataUri); uploadToKeyserver(mDataUri);
return true; return true;
case R.id.menu_key_view_export_file: case R.id.menu_key_view_export_file:
long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri); exportToFile(mDataUri);
mExportHelper.showExportKeysDialog(
new long[] { masterKeyId } , Constants.Path.APP_DIR_FILE_PUB,
// TODO this doesn't work?
((ViewKeyMainFragment) mTabsAdapter.getItem(0)).isSecretAvailable()
);
return true; return true;
case R.id.menu_key_view_share_default_fingerprint: case R.id.menu_key_view_share_default_fingerprint:
shareKey(mDataUri, true); shareKey(mDataUri, true);
@ -152,6 +149,21 @@ public class ViewKeyActivity extends ActionBarActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void exportToFile(Uri dataUri) {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri);
HashMap<String, Object> data = ProviderHelper.getGenericData(this,
baseUri,
new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET},
new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER});
mExportHelper.showExportKeysDialog(
new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)},
Constants.Path.APP_DIR_FILE,
((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) == 1)
);
}
private void uploadToKeyserver(Uri dataUri) { private void uploadToKeyserver(Uri dataUri) {
Intent uploadIntent = new Intent(this, UploadKeyActivity.class); Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
uploadIntent.setData(dataUri); uploadIntent.setData(dataUri);

View File

@ -1,6 +1,5 @@
/* /*
* Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2013 Bahtiar 'kalkin' Gadimov
* *
* 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
@ -19,7 +18,6 @@
package org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.net.Uri;
import android.nfc.NdefMessage; import android.nfc.NdefMessage;
import android.nfc.NdefRecord; import android.nfc.NdefRecord;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
@ -31,6 +29,9 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.widget.Toast; import android.widget.Toast;
import com.devspark.appmsg.AppMsg;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
@ -42,7 +43,6 @@ import java.io.IOException;
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback, public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
OnNdefPushCompleteCallback { OnNdefPushCompleteCallback {
// NFC
private NfcAdapter mNfcAdapter; private NfcAdapter mNfcAdapter;
private byte[] mSharedKeyringBytes; private byte[] mSharedKeyringBytes;
private static final int NFC_SENT = 1; private static final int NFC_SENT = 1;
@ -50,6 +50,8 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
initNfc();
} }
/** /**
@ -81,17 +83,15 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
* guarantee that this activity starts when receiving a beamed message. For now, this code * guarantee that this activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system. * uses the tag dispatch system.
*/ */
// get public keyring as byte array
long masterKeyId = ProviderHelper.getMasterKeyId(this, mDataUri);
try { try {
mSharedKeyringBytes = ProviderHelper.getPGPPublicKeyRing(this, masterKeyId).getEncoded(); // get public keyring as byte array
mSharedKeyringBytes = ProviderHelper.getPGPKeyRing(this, mDataUri).getEncoded();
NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME, NdefMessage msg = new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME)); mSharedKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
return msg; return msg;
} catch(IOException e) { } catch(IOException e) {
// not much trouble, but leave a note Log.e(Constants.TAG, "Error parsing keyring", e);
Log.e(Constants.TAG, "Error parsing keyring: ", e);
return null; return null;
} }
} }
@ -114,8 +114,8 @@ public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMess
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case NFC_SENT: case NFC_SENT:
Toast.makeText(getApplicationContext(), R.string.nfc_successfull, Toast.LENGTH_LONG) AppMsg.makeText(ViewKeyActivityJB.this, R.string.nfc_successfull,
.show(); AppMsg.STYLE_INFO).show();
break; break;
} }
} }

View File

@ -81,9 +81,6 @@ public class ViewKeyMainFragment extends Fragment implements
private Uri mDataUri; private Uri mDataUri;
// for activity
private boolean mSecretAvailable = false;
@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.view_key_main_fragment, container, false); View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
@ -227,8 +224,6 @@ public class ViewKeyMainFragment extends Fragment implements
mComment.setText(mainUserId[2]); mComment.setText(mainUserId[2]);
if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) { if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) {
mSecretAvailable = true;
mSecretKey.setTextColor(getResources().getColor(R.color.emphasis)); mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
mSecretKey.setText(R.string.secret_key_yes); mSecretKey.setText(R.string.secret_key_yes);
@ -243,8 +238,6 @@ public class ViewKeyMainFragment extends Fragment implements
} }
}); });
} else { } else {
mSecretAvailable = false;
mSecretKey.setTextColor(Color.BLACK); mSecretKey.setTextColor(Color.BLACK);
mSecretKey.setText(getResources().getString(R.string.secret_key_no)); mSecretKey.setText(getResources().getString(R.string.secret_key_no));
@ -333,11 +326,6 @@ public class ViewKeyMainFragment extends Fragment implements
} }
} }
/** Returns true if the key current displayed is known to have a secret key. */
public boolean isSecretAvailable() {
return mSecretAvailable;
}
private void encryptToContact(Uri dataUri) { private void encryptToContact(Uri dataUri) {
// TODO preselect from uri? should be feasible without trivial query // TODO preselect from uri? should be feasible without trivial query
long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

View File

@ -192,8 +192,7 @@
<TextView <TextView
android:id="@+id/secret_key" android:id="@+id/secret_key"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:typeface="monospace" />
</TableRow> </TableRow>
</TableLayout> </TableLayout>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_key_edit_save"
android:icon="@drawable/ic_action_save"
app:showAsAction="always"
android:title="@string/btn_save">
</item>
<item
android:id="@+id/menu_key_edit_export_file"
app:showAsAction="never"
android:title="@string/menu_export_key" />
<item
android:id="@+id/menu_key_edit_delete"
app:showAsAction="never"
android:title="@string/menu_delete_key" />
<item
android:id="@+id/menu_key_edit_cancel"
app:showAsAction="never"
android:title="@string/menu_key_edit_cancel" />
</menu>

View File

@ -2,7 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/menu_key_list_search" android:id="@+id/menu_key_list_search"
android:title="@string/menu_search" android:title="@string/menu_search"
@ -11,15 +10,16 @@
app:showAsAction="collapseActionView|ifRoom" /> app:showAsAction="collapseActionView|ifRoom" />
<item <item
android:id="@+id/menu_key_list_add" android:id="@+id/menu_key_list_import"
app:showAsAction="ifRoom|withText" app:showAsAction="ifRoom|withText"
android:icon="@drawable/ic_action_add_person" android:icon="@drawable/ic_action_add_person"
android:title="@string/menu_add_keys"> android:title="@string/menu_add_keys" />
<menu>
<item <item
android:id="@+id/menu_key_list_import" android:id="@+id/menu_key_list_export"
app:showAsAction="never" app:showAsAction="ifRoom|withText"
android:title="@string/menu_import" /> android:icon="@drawable/ic_action_import_export"
android:title="@string/menu_export_all_keys" />
<item <item
android:id="@+id/menu_key_list_create" android:id="@+id/menu_key_list_create"
@ -30,14 +30,5 @@
android:id="@+id/menu_key_list_create_expert" android:id="@+id/menu_key_list_create_expert"
app:showAsAction="never" app:showAsAction="never"
android:title="@string/menu_create_key_expert" /> android:title="@string/menu_create_key_expert" />
</menu>
</item>
<item
android:id="@+id/menu_key_list_export"
app:showAsAction="ifRoom|withText"
android:icon="@drawable/ic_action_import_export"
android:title="@string/menu_export_keys">
</item>
</menu> </menu>

View File

@ -5,14 +5,17 @@
android:id="@+id/menu_key_list_multi_export" android:id="@+id/menu_key_list_multi_export"
android:icon="@drawable/ic_action_import_export" android:icon="@drawable/ic_action_import_export"
android:title="@string/menu_export_key" /> android:title="@string/menu_export_key" />
<item <item
android:id="@+id/menu_key_list_multi_encrypt" android:id="@+id/menu_key_list_multi_encrypt"
android:icon="@drawable/ic_action_secure" android:icon="@drawable/ic_action_secure"
android:title="@string/menu_encrypt_to" /> android:title="@string/menu_encrypt_to" />
<item <item
android:id="@+id/menu_key_list_multi_delete" android:id="@+id/menu_key_list_multi_delete"
android:icon="@drawable/ic_action_discard" android:icon="@drawable/ic_action_discard"
android:title="@string/menu_delete_key" /> android:title="@string/menu_delete_key" />
<item <item
android:id="@+id/menu_key_list_multi_select_all" android:id="@+id/menu_key_list_multi_select_all"
android:icon="@drawable/ic_action_select_all" android:icon="@drawable/ic_action_select_all"

View File

@ -5,7 +5,7 @@
<item <item
android:id="@+id/menu_key_view_share" android:id="@+id/menu_key_view_share"
android:icon="@drawable/ic_action_share" android:icon="@drawable/ic_action_share"
app:showAsAction="ifRoom" app:showAsAction="always"
android:title="@string/menu_share"> android:title="@string/menu_share">
<menu> <menu>
<item <item
@ -48,9 +48,10 @@
</item> </item>
</menu> </menu>
</item> </item>
<item <item
android:id="@+id/menu_key_keyserver" android:id="@+id/menu_key_keyserver"
android:icon="@drawable/ic_action_import_export" android:icon="@drawable/ic_action_cloud"
app:showAsAction="always" app:showAsAction="always"
android:title="@string/menu_key_server"> android:title="@string/menu_key_server">
<menu> <menu>
@ -64,13 +65,17 @@
android:title="@string/menu_export_key_to_server" /> android:title="@string/menu_export_key_to_server" />
</menu> </menu>
</item> </item>
<item <item
android:id="@+id/menu_key_view_export_file" android:id="@+id/menu_key_view_export_file"
app:showAsAction="never" android:icon="@drawable/ic_action_import_export"
app:showAsAction="ifRoom"
android:title="@string/menu_export_key" /> android:title="@string/menu_export_key" />
<item <item
android:id="@+id/menu_key_view_delete" android:id="@+id/menu_key_view_delete"
app:showAsAction="never" android:icon="@drawable/ic_action_discard"
app:showAsAction="ifRoom"
android:title="@string/menu_delete_key" /> android:title="@string/menu_delete_key" />
</menu> </menu>

View File

@ -78,8 +78,6 @@
<string name="menu_import_from_qr_code">Import from QR Code</string> <string name="menu_import_from_qr_code">Import from QR Code</string>
<string name="menu_import">Import</string> <string name="menu_import">Import</string>
<string name="menu_import_from_nfc">Import from NFC</string> <string name="menu_import_from_nfc">Import from NFC</string>
<string name="menu_export_public_keys">Export all public keys</string>
<string name="menu_export_secret_keys">Export all secret keys</string>
<string name="menu_export_key">Export to file</string> <string name="menu_export_key">Export to file</string>
<string name="menu_delete_key">Delete key</string> <string name="menu_delete_key">Delete key</string>
<string name="menu_create_key">Create key</string> <string name="menu_create_key">Create key</string>
@ -104,7 +102,7 @@
<string name="menu_encrypt_to">Encrypt to…</string> <string name="menu_encrypt_to">Encrypt to…</string>
<string name="menu_select_all">Select all</string> <string name="menu_select_all">Select all</string>
<string name="menu_add_keys">Add keys</string> <string name="menu_add_keys">Add keys</string>
<string name="menu_export_keys">Export keys</string> <string name="menu_export_all_keys">Export all keys</string>
<!-- label --> <!-- label -->
<string name="label_sign">Sign</string> <string name="label_sign">Sign</string>