Merge remote-tracking branch 'origin/master' into external-test

Conflicts:
	OpenKeychain-Test/src/test/resources/extern/OpenPGP-Haskell
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java
	OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
This commit is contained in:
Vincent Breitmoser 2014-07-11 20:21:19 +02:00
commit 54bc874ce5
9 changed files with 296 additions and 76 deletions

View File

@ -53,6 +53,12 @@ import java.util.Set;
public class OpenPgpService extends RemoteService { public class OpenPgpService extends RemoteService {
static final String[] KEYRING_PROJECTION =
new String[]{
KeyRings._ID,
KeyRings.MASTER_KEY_ID,
};
/** /**
* Search database for key ids based on emails. * Search database for key ids based on emails.
* *
@ -70,7 +76,7 @@ public class OpenPgpService extends RemoteService {
for (String email : encryptionUserIds) { for (String email : encryptionUserIds) {
Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email); Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
Cursor cursor = getContentResolver().query(uri, null, null, null, null); Cursor cursor = getContentResolver().query(uri, KEYRING_PROJECTION, null, null, null);
try { try {
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID)); long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));

View File

@ -317,21 +317,21 @@ public class OperationResultParcel implements Parcelable {
public static class OperationLog implements Iterable<LogEntryParcel> { public static class OperationLog implements Iterable<LogEntryParcel> {
private final List<LogEntryParcel> parcels = new ArrayList<LogEntryParcel>(); private final List<LogEntryParcel> mParcels = new ArrayList<LogEntryParcel>();
/// Simple convenience method /// Simple convenience method
public void add(LogLevel level, LogType type, int indent, Object... parameters) { public void add(LogLevel level, LogType type, int indent, Object... parameters) {
Log.d(Constants.TAG, type.toString()); Log.d(Constants.TAG, type.toString());
parcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, parameters)); mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, parameters));
} }
public void add(LogLevel level, LogType type, int indent) { public void add(LogLevel level, LogType type, int indent) {
Log.d(Constants.TAG, type.toString()); Log.d(Constants.TAG, type.toString());
parcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null)); mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null));
} }
public boolean containsWarnings() { public boolean containsWarnings() {
for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(parcels.iterator())) { for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) { if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) {
return true; return true;
} }
@ -340,20 +340,20 @@ public class OperationResultParcel implements Parcelable {
} }
public void addAll(List<LogEntryParcel> parcels) { public void addAll(List<LogEntryParcel> parcels) {
parcels.addAll(parcels); mParcels.addAll(parcels);
} }
public List<LogEntryParcel> toList() { public List<LogEntryParcel> toList() {
return parcels; return mParcels;
} }
public boolean isEmpty() { public boolean isEmpty() {
return parcels.isEmpty(); return mParcels.isEmpty();
} }
@Override @Override
public Iterator<LogEntryParcel> iterator() { public Iterator<LogEntryParcel> iterator() {
return parcels.iterator(); return mParcels.iterator();
} }
} }

View File

@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
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;
@ -214,9 +215,17 @@ public class EditKeyFragment extends LoaderFragment implements
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mUserIdsAddedData); mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mUserIdsAddedData);
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter); mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0); mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0, mSaveKeyringParcel);
mSubkeysList.setAdapter(mSubkeysAdapter); mSubkeysList.setAdapter(mSubkeysAdapter);
mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long keyId = mSubkeysAdapter.getKeyId(position);
editSubkey(keyId);
}
});
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys); mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter); mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
@ -342,6 +351,46 @@ public class EditKeyFragment extends LoaderFragment implements
}); });
} }
private void editSubkey(final long keyId) {
Handler returnHandler = new Handler() {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case EditSubkeyDialogFragment.MESSAGE_CHANGE_EXPIRY:
// toggle
// if (mSaveKeyringParcel.changePrimaryUserId != null
// && mSaveKeyringParcel.changePrimaryUserId.equals(userId)) {
// mSaveKeyringParcel.changePrimaryUserId = null;
// } else {
// mSaveKeyringParcel.changePrimaryUserId = userId;
// }
break;
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
// toggle
if (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
mSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
} else {
mSaveKeyringParcel.mRevokeSubKeys.add(keyId);
}
break;
}
getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad();
}
};
// Create a new Messenger for the communication back
final Messenger messenger = new Messenger(returnHandler);
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
public void run() {
EditSubkeyDialogFragment dialogFragment =
EditSubkeyDialogFragment.newInstance(messenger);
dialogFragment.show(getActivity().getSupportFragmentManager(), "editSubkeyDialog");
}
});
}
private void addUserId() { private void addUserId() {
mUserIdsAddedAdapter.add(new UserIdsAddedAdapter.UserIdModel()); mUserIdsAddedAdapter.add(new UserIdsAddedAdapter.UserIdModel());
} }

View File

@ -32,14 +32,15 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import java.util.Date; import java.util.Date;
public class SubkeysAdapter extends CursorAdapter { public class SubkeysAdapter extends CursorAdapter {
private LayoutInflater mInflater; private LayoutInflater mInflater;
private SaveKeyringParcel mSaveKeyringParcel;
private boolean hasAnySecret; private boolean hasAnySecret;
private ColorStateList mDefaultTextColor; private ColorStateList mDefaultTextColor;
public static final String[] SUBKEYS_PROJECTION = new String[]{ public static final String[] SUBKEYS_PROJECTION = new String[]{
@ -71,10 +72,21 @@ public class SubkeysAdapter extends CursorAdapter {
private static final int INDEX_EXPIRY = 11; private static final int INDEX_EXPIRY = 11;
private static final int INDEX_FINGERPRINT = 12; private static final int INDEX_FINGERPRINT = 12;
public SubkeysAdapter(Context context, Cursor c, int flags) { public SubkeysAdapter(Context context, Cursor c, int flags,
SaveKeyringParcel saveKeyringParcel) {
super(context, c, flags); super(context, c, flags);
mInflater = LayoutInflater.from(context); mInflater = LayoutInflater.from(context);
mSaveKeyringParcel = saveKeyringParcel;
}
public SubkeysAdapter(Context context, Cursor c, int flags) {
this(context, c, flags, null);
}
public long getKeyId(int position) {
mCursor.moveToPosition(position);
return mCursor.getLong(INDEX_KEY_ID);
} }
@Override @Override
@ -94,79 +106,94 @@ public class SubkeysAdapter extends CursorAdapter {
@Override @Override
public void bindView(View view, Context context, Cursor cursor) { public void bindView(View view, Context context, Cursor cursor) {
TextView keyId = (TextView) view.findViewById(R.id.keyId); TextView vKeyId = (TextView) view.findViewById(R.id.keyId);
TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); TextView vKeyDetails = (TextView) view.findViewById(R.id.keyDetails);
TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry); TextView vKeyExpiry = (TextView) view.findViewById(R.id.keyExpiry);
ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); ImageView vMasterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); ImageView vCertifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); ImageView vEncryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); ImageView vSignIcon = (ImageView) view.findViewById(R.id.ic_signKey);
ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey); ImageView vRevokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey);
ImageView vEditImage = (ImageView) view.findViewById(R.id.edit_image);
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(INDEX_KEY_ID)); long keyId = cursor.getLong(INDEX_KEY_ID);
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
String algorithmStr = PgpKeyHelper.getAlgorithmInfo( String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
context, context,
cursor.getInt(INDEX_ALGORITHM), cursor.getInt(INDEX_ALGORITHM),
cursor.getInt(INDEX_KEY_SIZE) cursor.getInt(INDEX_KEY_SIZE)
); );
keyId.setText(keyIdStr); vKeyId.setText(keyIdStr);
// may be set with additional "stripped" later on // may be set with additional "stripped" later on
if (hasAnySecret && cursor.getInt(INDEX_HAS_SECRET) == 0) { if (hasAnySecret && cursor.getInt(INDEX_HAS_SECRET) == 0) {
keyDetails.setText(algorithmStr + ", " + vKeyDetails.setText(algorithmStr + ", " +
context.getString(R.string.key_stripped)); context.getString(R.string.key_stripped));
} else { } else {
keyDetails.setText(algorithmStr); vKeyDetails.setText(algorithmStr);
} }
// Set icons according to properties // Set icons according to properties
masterKeyIcon.setVisibility(cursor.getInt(INDEX_RANK) == 0 ? View.VISIBLE : View.INVISIBLE); vMasterKeyIcon.setVisibility(cursor.getInt(INDEX_RANK) == 0 ? View.VISIBLE : View.INVISIBLE);
certifyIcon.setVisibility(cursor.getInt(INDEX_CAN_CERTIFY) != 0 ? View.VISIBLE : View.GONE); vCertifyIcon.setVisibility(cursor.getInt(INDEX_CAN_CERTIFY) != 0 ? View.VISIBLE : View.GONE);
encryptIcon.setVisibility(cursor.getInt(INDEX_CAN_ENCRYPT) != 0 ? View.VISIBLE : View.GONE); vEncryptIcon.setVisibility(cursor.getInt(INDEX_CAN_ENCRYPT) != 0 ? View.VISIBLE : View.GONE);
signIcon.setVisibility(cursor.getInt(INDEX_CAN_SIGN) != 0 ? View.VISIBLE : View.GONE); vSignIcon.setVisibility(cursor.getInt(INDEX_CAN_SIGN) != 0 ? View.VISIBLE : View.GONE);
boolean valid = true; boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
if (cursor.getInt(INDEX_IS_REVOKED) > 0) {
revokedKeyIcon.setVisibility(View.VISIBLE);
valid = false; // for edit key
} else { if (mSaveKeyringParcel != null) {
keyId.setTextColor(mDefaultTextColor); boolean revokeThisSubkey = (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId));
keyDetails.setTextColor(mDefaultTextColor);
keyExpiry.setTextColor(mDefaultTextColor);
revokedKeyIcon.setVisibility(View.GONE); if (revokeThisSubkey) {
if (!isRevoked) {
isRevoked = true;
}
} }
vEditImage.setVisibility(View.VISIBLE);
} else {
vEditImage.setVisibility(View.GONE);
}
if (isRevoked) {
vRevokedKeyIcon.setVisibility(View.VISIBLE);
} else {
vKeyId.setTextColor(mDefaultTextColor);
vKeyDetails.setTextColor(mDefaultTextColor);
vKeyExpiry.setTextColor(mDefaultTextColor);
vRevokedKeyIcon.setVisibility(View.GONE);
}
boolean isExpired;
if (!cursor.isNull(INDEX_EXPIRY)) { if (!cursor.isNull(INDEX_EXPIRY)) {
Date expiryDate = new Date(cursor.getLong(INDEX_EXPIRY) * 1000); Date expiryDate = new Date(cursor.getLong(INDEX_EXPIRY) * 1000);
isExpired = expiryDate.before(new Date());
valid = valid && expiryDate.after(new Date()); vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": "
keyExpiry.setText( + DateFormat.getDateFormat(context).format(expiryDate));
context.getString(R.string.label_expiry) + ": " +
DateFormat.getDateFormat(context).format(expiryDate)
);
} else { } else {
keyExpiry.setText( isExpired = false;
context.getString(R.string.label_expiry) + ": " +
context.getString(R.string.none) vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": " + context.getString(R.string.none));
);
} }
// if key is expired or revoked, strike through text // if key is expired or revoked, strike through text
if (!valid) { boolean isInvalid = isRevoked || isExpired;
keyId.setText(OtherHelper.strikeOutText(keyId.getText())); if (isInvalid) {
keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText())); vKeyId.setText(OtherHelper.strikeOutText(vKeyId.getText()));
keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText())); vKeyDetails.setText(OtherHelper.strikeOutText(vKeyDetails.getText()));
vKeyExpiry.setText(OtherHelper.strikeOutText(vKeyExpiry.getText()));
} }
keyId.setEnabled(valid); vKeyId.setEnabled(!isInvalid);
keyDetails.setEnabled(valid); vKeyDetails.setEnabled(!isInvalid);
keyExpiry.setEnabled(valid); vKeyExpiry.setEnabled(!isInvalid);
} }
@Override @Override
public View newView(Context context, Cursor cursor, ViewGroup parent) { public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(R.layout.view_key_keys_item, null); View view = mInflater.inflate(R.layout.view_key_subkey_item, null);
if (mDefaultTextColor == null) { if (mDefaultTextColor == null) {
TextView keyId = (TextView) view.findViewById(R.id.keyId); TextView keyId = (TextView) view.findViewById(R.id.keyId);
mDefaultTextColor = keyId.getTextColors(); mDefaultTextColor = keyId.getTextColors();
@ -177,13 +204,21 @@ public class SubkeysAdapter extends CursorAdapter {
// Disable selection of items, http://stackoverflow.com/a/4075045 // Disable selection of items, http://stackoverflow.com/a/4075045
@Override @Override
public boolean areAllItemsEnabled() { public boolean areAllItemsEnabled() {
if (mSaveKeyringParcel == null) {
return false; return false;
} else {
return super.areAllItemsEnabled();
}
} }
// Disable selection of items, http://stackoverflow.com/a/4075045 // Disable selection of items, http://stackoverflow.com/a/4075045
@Override @Override
public boolean isEnabled(int position) { public boolean isEnabled(int position) {
if (mSaveKeyringParcel == null) {
return false; return false;
} else {
return super.isEnabled(position);
}
} }
} }

View File

@ -40,9 +40,7 @@ import java.util.ArrayList;
public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener { public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener {
private LayoutInflater mInflater; private LayoutInflater mInflater;
private final ArrayList<Boolean> mCheckStates; private final ArrayList<Boolean> mCheckStates;
private SaveKeyringParcel mSaveKeyringParcel; private SaveKeyringParcel mSaveKeyringParcel;
public static final String[] USER_IDS_PROJECTION = new String[]{ public static final String[] USER_IDS_PROJECTION = new String[]{
@ -60,7 +58,6 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
private static final int INDEX_IS_PRIMARY = 4; private static final int INDEX_IS_PRIMARY = 4;
private static final int INDEX_IS_REVOKED = 5; private static final int INDEX_IS_REVOKED = 5;
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes, public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
SaveKeyringParcel saveKeyringParcel) { SaveKeyringParcel saveKeyringParcel) {
super(context, c, flags); super(context, c, flags);
@ -139,10 +136,13 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId)); && mSaveKeyringParcel.mChangePrimaryUserId.equals(userId));
boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId)); boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId));
// only if primary user id will be changed
// (this is not triggered if the user id is currently the primary one)
if (changeAnyPrimaryUserId) { if (changeAnyPrimaryUserId) {
// change all user ids, only this one should be primary // change _all_ primary user ids and set new one to true
isPrimary = changeThisPrimaryUserId; isPrimary = changeThisPrimaryUserId;
} }
if (revokeThisUserId) { if (revokeThisUserId) {
if (!isRevoked) { if (!isRevoked) {
isRevoked = true; isRevoked = true;
@ -233,7 +233,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
@Override @Override
public View newView(Context context, Cursor cursor, ViewGroup parent) { public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = mInflater.inflate(R.layout.view_key_userids_item, null); View view = mInflater.inflate(R.layout.view_key_user_id_item, null);
// only need to do this once ever, since mShowCheckBoxes is final // only need to do this once ever, since mShowCheckBoxes is final
view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE); view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
return view; return view;

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui.dialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
public class EditSubkeyDialogFragment extends DialogFragment {
private static final String ARG_MESSENGER = "messenger";
public static final int MESSAGE_CHANGE_EXPIRY = 1;
public static final int MESSAGE_REVOKE = 2;
private Messenger mMessenger;
/**
* Creates new instance of this dialog fragment
*/
public static EditSubkeyDialogFragment newInstance(Messenger messenger) {
EditSubkeyDialogFragment frag = new EditSubkeyDialogFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_MESSENGER, messenger);
frag.setArguments(args);
return frag;
}
/**
* Creates dialog
*/
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity());
CharSequence[] array = getResources().getStringArray(R.array.edit_key_edit_subkey);
builder.setTitle(R.string.edit_key_edit_subkey_title);
builder.setItems(array, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
sendMessageToHandler(MESSAGE_CHANGE_EXPIRY, null);
break;
case 1:
sendMessageToHandler(MESSAGE_REVOKE, null);
break;
default:
break;
}
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
}
});
return builder.show();
}
/**
* Send message back to handler which is initialized in a activity
*
* @param what Message integer you want to send
*/
private void sendMessageToHandler(Integer what, Bundle data) {
Message msg = Message.obtain();
msg.what = what;
if (data != null) {
msg.setData(data);
}
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
} catch (NullPointerException e) {
Log.w(Constants.TAG, "Messenger is null!", e);
}
}
}

View File

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight" android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingRight="3dip"
android:singleLine="true"> android:singleLine="true">
<ImageView <ImageView
@ -13,28 +12,44 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:src="@drawable/key_small" android:src="@drawable/key_small"
android:layout_marginLeft="8dp" /> android:padding="8dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/edit_image"
android:src="@drawable/ic_action_edit"
android:padding="8dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_toRightOf="@id/ic_masterKey"
android:layout_toLeftOf="@id/edit_image"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_marginRight="8dp"
android:layout_marginLeft="8dp" android:id="@+id/linearLayout">
android:layout_marginRight="8dp">
<LinearLayout <LinearLayout
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="2dip" android:paddingBottom="2dip"
android:paddingTop="2dip"> android:paddingTop="2dip">
<TextView <TextView
android:id="@+id/keyId" android:id="@+id/keyId"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_key_id" android:text="0x00000000"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:typeface="monospace" android:typeface="monospace"
android:layout_weight="1" /> android:layout_weight="1" />
@ -75,8 +90,8 @@
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_width="match_parent"
android:layout_height="fill_parent"> android:layout_height="match_parent">
<TextView <TextView
android:id="@+id/keyDetails" android:id="@+id/keyDetails"
@ -94,8 +109,9 @@
android:text="Expiry: 4/7/2016" android:text="Expiry: 4/7/2016"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_gravity="right" /> android:layout_gravity="right" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout>

View File

@ -63,7 +63,6 @@
</LinearLayout> </LinearLayout>
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"

View File

@ -480,6 +480,11 @@
<item>Change to Primary Identity</item> <item>Change to Primary Identity</item>
<item>Revoke Identity</item> <item>Revoke Identity</item>
</string-array> </string-array>
<string name="edit_key_edit_subkey_title">Select an action!</string>
<string-array name="edit_key_edit_subkey">
<item>Change Expiry</item>
<item>Revoke Subkey</item>
</string-array>
<!-- Navigation Drawer --> <!-- Navigation Drawer -->
<string name="nav_keys">Keys</string> <string name="nav_keys">Keys</string>