Fixes for expiry UI

This commit is contained in:
Dominik Schürmann 2014-08-18 11:02:41 +02:00
parent 56fb822034
commit 3e7ce0008f
6 changed files with 109 additions and 67 deletions

View File

@ -406,10 +406,10 @@ public class EditKeyFragment extends LoaderFragment implements
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
switch (message.what) { switch (message.what) {
case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY_DATE: case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY:
mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry =
(Long) message.getData().getSerializable( (Long) message.getData().getSerializable(
EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY);
break; break;
} }
getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad();

View File

@ -35,7 +35,9 @@ 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 org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
public class SubkeysAdapter extends CursorAdapter { public class SubkeysAdapter extends CursorAdapter {
private LayoutInflater mInflater; private LayoutInflater mInflater;
@ -198,9 +200,13 @@ public class SubkeysAdapter extends CursorAdapter {
boolean isExpired; boolean isExpired;
if (expiryDate != null) { if (expiryDate != null) {
isExpired = expiryDate.before(new Date()); isExpired = expiryDate.before(new Date());
Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
expiryCal.setTime(expiryDate);
// convert from UTC to time zone of device
expiryCal.setTimeZone(TimeZone.getDefault());
vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": " vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": "
+ DateFormat.getDateFormat(context).format(expiryDate)); + DateFormat.getDateFormat(context).format(expiryCal.getTime()));
} else { } else {
isExpired = false; isExpired = false;

View File

@ -33,8 +33,10 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone;
public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAdd> { public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAdd> {
private LayoutInflater mInflater; private LayoutInflater mInflater;
@ -108,9 +110,13 @@ public class SubkeysAddedAdapter extends ArrayAdapter<SaveKeyringParcel.SubkeyAd
if (holder.mModel.mExpiry != 0L) { if (holder.mModel.mExpiry != 0L) {
Date expiryDate = new Date(holder.mModel.mExpiry * 1000); Date expiryDate = new Date(holder.mModel.mExpiry * 1000);
Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
expiryCal.setTime(expiryDate);
// convert from UTC to time zone of device
expiryCal.setTimeZone(TimeZone.getDefault());
holder.vKeyExpiry.setText(getContext().getString(R.string.label_expiry) + ": " holder.vKeyExpiry.setText(getContext().getString(R.string.label_expiry) + ": "
+ DateFormat.getDateFormat(getContext()).format(expiryDate)); + DateFormat.getDateFormat(getContext()).format(expiryCal.getTime()));
} else { } else {
holder.vKeyExpiry.setText(getContext().getString(R.string.label_expiry) + ": " holder.vKeyExpiry.setText(getContext().getString(R.string.label_expiry) + ": "
+ getContext().getString(R.string.none)); + getContext().getString(R.string.none));

View File

@ -132,7 +132,10 @@ public class AddSubkeyDialogFragment extends DialogFragment {
}); });
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
mExpiryDatePicker.setMinDate(new Date().getTime() + DateUtils.DAY_IN_MILLIS); // date picker works based on default time zone
Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault());
minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today)
mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime());
} }
ArrayList<Choice> choices = new ArrayList<Choice>(); ArrayList<Choice> choices = new ArrayList<Choice>();

View File

@ -25,9 +25,10 @@ import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.text.format.DateUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker; import android.widget.DatePicker;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@ -40,17 +41,15 @@ import java.util.TimeZone;
public class EditSubkeyExpiryDialogFragment extends DialogFragment { public class EditSubkeyExpiryDialogFragment extends DialogFragment {
private static final String ARG_MESSENGER = "messenger"; private static final String ARG_MESSENGER = "messenger";
private static final String ARG_CREATION_DATE = "creation_date"; private static final String ARG_CREATION = "creation";
private static final String ARG_EXPIRY_DATE = "expiry_date"; private static final String ARG_EXPIRY = "expiry";
public static final int MESSAGE_NEW_EXPIRY_DATE = 1; public static final int MESSAGE_NEW_EXPIRY = 1;
public static final int MESSAGE_CANCEL = 2; public static final int MESSAGE_CANCEL = 2;
public static final String MESSAGE_DATA_EXPIRY_DATE = "expiry_date"; public static final String MESSAGE_DATA_EXPIRY = "expiry";
private Messenger mMessenger; private Messenger mMessenger;
private DatePicker mDatePicker;
/** /**
* Creates new instance of this dialog fragment * Creates new instance of this dialog fragment
*/ */
@ -59,8 +58,8 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
EditSubkeyExpiryDialogFragment frag = new EditSubkeyExpiryDialogFragment(); EditSubkeyExpiryDialogFragment frag = new EditSubkeyExpiryDialogFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putParcelable(ARG_MESSENGER, messenger); args.putParcelable(ARG_MESSENGER, messenger);
args.putSerializable(ARG_CREATION_DATE, creationDate); args.putSerializable(ARG_CREATION, creationDate);
args.putSerializable(ARG_EXPIRY_DATE, expiryDate); args.putSerializable(ARG_EXPIRY, expiryDate);
frag.setArguments(args); frag.setArguments(args);
@ -74,13 +73,13 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final Activity activity = getActivity(); final Activity activity = getActivity();
mMessenger = getArguments().getParcelable(ARG_MESSENGER); mMessenger = getArguments().getParcelable(ARG_MESSENGER);
long creationDate = getArguments().getLong(ARG_CREATION_DATE); long creation = getArguments().getLong(ARG_CREATION);
long expiryDate = getArguments().getLong(ARG_EXPIRY_DATE); long expiry = getArguments().getLong(ARG_EXPIRY);
Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
creationCal.setTime(new Date(creationDate * 1000)); creationCal.setTime(new Date(creation * 1000));
final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
expiryCal.setTime(new Date(expiryDate * 1000)); expiryCal.setTime(new Date(expiry * 1000));
// date picker works with default time zone, we need to convert from UTC to default timezone // date picker works with default time zone, we need to convert from UTC to default timezone
creationCal.setTimeZone(TimeZone.getDefault()); creationCal.setTimeZone(TimeZone.getDefault());
@ -96,44 +95,64 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
View view = inflater.inflate(R.layout.edit_subkey_expiry_dialog, null); View view = inflater.inflate(R.layout.edit_subkey_expiry_dialog, null);
alert.setView(view); alert.setView(view);
mDatePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker); final CheckBox noExpiry = (CheckBox) view.findViewById(R.id.edit_subkey_expiry_no_expiry);
final DatePicker datePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker);
// set default date noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
if (expiryDate == 0L) { @Override
// if key has no expiry, set it to creation date +1 day public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
datePicker.setVisibility(View.GONE);
} else {
datePicker.setVisibility(View.VISIBLE);
}
}
});
// init date picker with default selected date
if (expiry == 0L) {
noExpiry.setChecked(true);
datePicker.setVisibility(View.GONE);
Calendar todayCal = Calendar.getInstance(TimeZone.getDefault());
if (creationCal.after(todayCal)) {
// Note: This is just for the rare cases where creation is _after_ today
// set it to creation date +1 day (don't set it to creationCal, it would break crash
// datePicker.setMinDate() execution with IllegalArgumentException
Calendar creationCalPlusOne = (Calendar) creationCal.clone(); Calendar creationCalPlusOne = (Calendar) creationCal.clone();
creationCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1);
mDatePicker.init( datePicker.init(
creationCalPlusOne.get(Calendar.YEAR), creationCalPlusOne.get(Calendar.YEAR),
creationCalPlusOne.get(Calendar.MONTH), creationCalPlusOne.get(Calendar.MONTH),
creationCalPlusOne.get(Calendar.DAY_OF_MONTH), creationCalPlusOne.get(Calendar.DAY_OF_MONTH),
null null
); );
} else {
// set date picker to current expiry date +1 day
Calendar expiryCalPlusOne = (Calendar) expiryCal.clone(); } else {
expiryCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); // normally, just init with today
mDatePicker.init( datePicker.init(
expiryCalPlusOne.get(Calendar.YEAR), todayCal.get(Calendar.YEAR),
expiryCalPlusOne.get(Calendar.MONTH), todayCal.get(Calendar.MONTH),
expiryCalPlusOne.get(Calendar.DAY_OF_MONTH), todayCal.get(Calendar.DAY_OF_MONTH),
null
);
}
} else {
noExpiry.setChecked(false);
datePicker.setVisibility(View.VISIBLE);
// set date picker to current expiry
datePicker.init(
expiryCal.get(Calendar.YEAR),
expiryCal.get(Calendar.MONTH),
expiryCal.get(Calendar.DAY_OF_MONTH),
null null
); );
} }
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
// will crash with IllegalArgumentException if we set a min date datePicker.setMinDate(creationCal.getTime().getTime());
// that is before creation date
if (expiryDate == 0L || creationCal.before(expiryCal)) {
mDatePicker.setMinDate(creationCal.getTime().getTime()
+ DateUtils.DAY_IN_MILLIS);
} else {
// set min to expiry date
mDatePicker.setMinDate(expiryCal.getTime().getTime()
+ DateUtils.DAY_IN_MILLIS);
}
} }
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@ -141,30 +160,28 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dismiss(); dismiss();
long expiry;
if (noExpiry.isChecked()) {
expiry = 0L;
} else {
Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault());
//noinspection ResourceType //noinspection ResourceType
selectedCal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); selectedCal.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth());
// date picker uses default time zone, we need to convert to UTC // date picker uses default time zone, we need to convert to UTC
selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); selectedCal.setTimeZone(TimeZone.getTimeZone("UTC"));
long numDays = (selectedCal.getTimeInMillis() / 86400000) long numDays = (selectedCal.getTimeInMillis() / 86400000)
- (expiryCal.getTimeInMillis() / 86400000); - (expiryCal.getTimeInMillis() / 86400000);
if (numDays > 0) { if (numDays <= 0) {
Bundle data = new Bundle(); Log.e(Constants.TAG, "Should not happen! Expiry num of days <= 0!");
data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); throw new RuntimeException();
sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data);
} }
expiry = selectedCal.getTime().getTime() / 1000;
} }
});
alert.setNeutralButton(R.string.btn_no_date, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, 0L); data.putSerializable(MESSAGE_DATA_EXPIRY, expiry);
sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); sendMessageToHandler(MESSAGE_NEW_EXPIRY, data);
} }
}); });

View File

@ -4,6 +4,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<CheckBox
android:id="@+id/edit_subkey_expiry_no_expiry"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:checked="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/btn_no_date" />
<DatePicker <DatePicker
android:id="@+id/edit_subkey_expiry_date_picker" android:id="@+id/edit_subkey_expiry_date_picker"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"