From 50f404ccddd30becf1d69129f493a2620110ed4d Mon Sep 17 00:00:00 2001 From: rohands Date: Sun, 20 Sep 2015 18:57:18 +0530 Subject: Mousehints --- .../keychain/ui/KeyListFragment.java | 3 + .../keychain/ui/ViewKeyActivity.java | 10 +++ .../keychain/ui/util/LongClick.java | 85 ++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index ce6994ba4..4e1f41ba0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -67,6 +67,7 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; +import org.sufficientlysecure.keychain.ui.util.LongClick; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.FabContainer; import org.sufficientlysecure.keychain.util.Log; @@ -706,6 +707,8 @@ public class KeyListFragment extends LoaderFragment final KeyItemViewHolder holder = (KeyItemViewHolder) view.getTag(); holder.mSlinger.setVisibility(View.VISIBLE); + + LongClick.setup(holder.mSlingerButton,getString(R.string.exchange_keys)); holder.mSlingerButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 930c1fc26..f9bde850e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -79,6 +79,7 @@ import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; +import org.sufficientlysecure.keychain.ui.util.LongClick; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; import org.sufficientlysecure.keychain.ui.util.Notify.Style; @@ -180,6 +181,15 @@ public class ViewKeyActivity extends BaseNfcActivity implements mQrCodeLayout = (CardView) findViewById(R.id.view_key_qr_code_layout); mRotateSpin = AnimationUtils.loadAnimation(this, R.anim.rotate_spin); + + //Long Click Listeners implemented + + LongClick.setup(mActionEncryptFile,getString(R.string.encrypt_files)); + LongClick.setup(mActionEncryptText,getString(R.string.encrypt_text)); + LongClick.setup(mActionNfc,getString(R.string.share_nfc)); + LongClick.setup(mFab,getString(R.string.exchange_keys)); + + mRotateSpin.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java new file mode 100644 index 000000000..c41f77767 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java @@ -0,0 +1,85 @@ +package org.sufficientlysecure.keychain.ui.util; + +/** + * Created by rohan on 20/9/15. + */ +import android.content.Context; +import android.graphics.Rect; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.View; +import android.widget.Toast; +public class LongClick { + private static final int ESTIMATED_TOAST_HEIGHT_DIPS = 48; + public static void setup(View view) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, view.getContentDescription()); + } + }); + } + + public static void setup(View view, final int textResId) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, view.getContext().getString(textResId)); + } + }); + } + + public static void setup(View view, final CharSequence text) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, text); + } + }); + } + + public static void remove(final View view) { + view.setOnLongClickListener(null); + } + + private static boolean showLongClickText(View view, CharSequence text) { + if (TextUtils.isEmpty(text)) { + return false; + } + + final int[] screenPos = new int[2]; // origin is device display + final Rect displayFrame = new Rect(); // includes decorations (e.g. status bar) + view.getLocationOnScreen(screenPos); + view.getWindowVisibleDisplayFrame(displayFrame); + + final Context context = view.getContext(); + final int viewWidth = view.getWidth(); + final int viewHeight = view.getHeight(); + final int viewCenterX = screenPos[0] + viewWidth / 2; + final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; + final int estimatedToastHeight = (int) (ESTIMATED_TOAST_HEIGHT_DIPS + * context.getResources().getDisplayMetrics().density); + + Toast longClickText = Toast.makeText(context, text, Toast.LENGTH_SHORT); + boolean showBelow = screenPos[1] < estimatedToastHeight; + if (showBelow) { + // Show below + // Offsets are after decorations (e.g. status bar) are factored in + longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, + viewCenterX - screenWidth / 2, + screenPos[1] - displayFrame.top + viewHeight); + } else { + // Show above + // Offsets are after decorations (e.g. status bar) are factored in + // NOTE: We can't use Gravity.BOTTOM because when the keyboard is up + // its height isn't factored in. + longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, + viewCenterX - screenWidth / 2, + screenPos[1] - displayFrame.top - estimatedToastHeight); + } + + longClickText.show(); + return true; + } + +} -- cgit v1.2.3 From afbf2b36cf07e3225e186f1ce555927e5240f100 Mon Sep 17 00:00:00 2001 From: rohands Date: Sun, 20 Sep 2015 20:20:43 +0530 Subject: Updated --- .../sufficientlysecure/keychain/ui/KeyListFragment.java | 2 +- .../sufficientlysecure/keychain/ui/ViewKeyActivity.java | 8 ++++---- .../sufficientlysecure/keychain/ui/util/LongClick.java | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 4e1f41ba0..09d2b9fcf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -708,7 +708,7 @@ public class KeyListFragment extends LoaderFragment holder.mSlinger.setVisibility(View.VISIBLE); - LongClick.setup(holder.mSlingerButton,getString(R.string.exchange_keys)); + LongClick.setup(holder.mSlingerButton); holder.mSlingerButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index f9bde850e..6e30f7a22 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -184,10 +184,10 @@ public class ViewKeyActivity extends BaseNfcActivity implements //Long Click Listeners implemented - LongClick.setup(mActionEncryptFile,getString(R.string.encrypt_files)); - LongClick.setup(mActionEncryptText,getString(R.string.encrypt_text)); - LongClick.setup(mActionNfc,getString(R.string.share_nfc)); - LongClick.setup(mFab,getString(R.string.exchange_keys)); + LongClick.setup(mActionEncryptFile); + LongClick.setup(mActionEncryptText); + LongClick.setup(mActionNfc); + LongClick.setup(mFab); mRotateSpin.setAnimationListener(new AnimationListener() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java index c41f77767..5b0bcbb78 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java @@ -3,6 +3,22 @@ package org.sufficientlysecure.keychain.ui.util; /** * Created by rohan on 20/9/15. */ +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + import android.content.Context; import android.graphics.Rect; import android.text.TextUtils; -- cgit v1.2.3 From 8703b5f4a9268f43531a57ab5d27ab879882b449 Mon Sep 17 00:00:00 2001 From: rohands Date: Tue, 22 Sep 2015 23:06:26 +0530 Subject: Class names and string names are updated --- .../keychain/ui/KeyListFragment.java | 4 +- .../keychain/ui/ViewKeyActivity.java | 12 +-- .../keychain/ui/util/ContentDescriptionHint.java | 101 +++++++++++++++++++++ .../keychain/ui/util/LongClick.java | 101 --------------------- 4 files changed, 109 insertions(+), 109 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 09d2b9fcf..2b6d786d4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -67,7 +67,7 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.ui.util.LongClick; +import org.sufficientlysecure.keychain.ui.util.ContentDescriptionHint; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.FabContainer; import org.sufficientlysecure.keychain.util.Log; @@ -708,7 +708,7 @@ public class KeyListFragment extends LoaderFragment holder.mSlinger.setVisibility(View.VISIBLE); - LongClick.setup(holder.mSlingerButton); + ContentDescriptionHint.setup(holder.mSlingerButton); holder.mSlingerButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 6e30f7a22..a09e74abe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -79,7 +79,7 @@ import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; -import org.sufficientlysecure.keychain.ui.util.LongClick; +import org.sufficientlysecure.keychain.ui.util.ContentDescriptionHint; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener; import org.sufficientlysecure.keychain.ui.util.Notify.Style; @@ -182,12 +182,12 @@ public class ViewKeyActivity extends BaseNfcActivity implements mRotateSpin = AnimationUtils.loadAnimation(this, R.anim.rotate_spin); - //Long Click Listeners implemented + //ContentDescriptionHint Listeners implemented - LongClick.setup(mActionEncryptFile); - LongClick.setup(mActionEncryptText); - LongClick.setup(mActionNfc); - LongClick.setup(mFab); + ContentDescriptionHint.setup(mActionEncryptFile); + ContentDescriptionHint.setup(mActionEncryptText); + ContentDescriptionHint.setup(mActionNfc); + ContentDescriptionHint.setup(mFab); mRotateSpin.setAnimationListener(new AnimationListener() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java new file mode 100644 index 000000000..8e45a20e9 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java @@ -0,0 +1,101 @@ +package org.sufficientlysecure.keychain.ui.util; + +/** + * Created by rohan on 20/9/15. + */ +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +import android.content.Context; +import android.graphics.Rect; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.View; +import android.widget.Toast; +public class ContentDescriptionHint { + private static final int ESTIMATED_TOAST_HEIGHT_DIPS = 48; + public static void setup(View view) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, view.getContentDescription()); + } + }); + } + + public static void setup(View view, final int textResId) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, view.getContext().getString(textResId)); + } + }); + } + + public static void setup(View view, final CharSequence text) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View view) { + return showLongClickText(view, text); + } + }); + } + + public static void remove(final View view) { + view.setOnLongClickListener(null); + } + + private static boolean showLongClickText(View view, CharSequence text) { + if (TextUtils.isEmpty(text)) { + return false; + } + + final int[] screenPos = new int[2]; // origin is device display + final Rect displayFrame = new Rect(); // includes decorations (e.g. status bar) + view.getLocationOnScreen(screenPos); + view.getWindowVisibleDisplayFrame(displayFrame); + + final Context context = view.getContext(); + final int viewWidth = view.getWidth(); + final int viewHeight = view.getHeight(); + final int viewCenterX = screenPos[0] + viewWidth / 2; + final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; + final int estimatedToastHeight = (int) (ESTIMATED_TOAST_HEIGHT_DIPS + * context.getResources().getDisplayMetrics().density); + + Toast longClickText = Toast.makeText(context, text, Toast.LENGTH_SHORT); + boolean showBelow = screenPos[1] < estimatedToastHeight; + if (showBelow) { + // Show below + // Offsets are after decorations (e.g. status bar) are factored in + longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, + viewCenterX - screenWidth / 2, + screenPos[1] - displayFrame.top + viewHeight); + } else { + // Show above + // Offsets are after decorations (e.g. status bar) are factored in + // NOTE: We can't use Gravity.BOTTOM because when the keyboard is up + // its height isn't factored in. + longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, + viewCenterX - screenWidth / 2, + screenPos[1] - displayFrame.top - estimatedToastHeight); + } + + longClickText.show(); + return true; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java deleted file mode 100644 index 5b0bcbb78..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/LongClick.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.sufficientlysecure.keychain.ui.util; - -/** - * Created by rohan on 20/9/15. - */ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -import android.content.Context; -import android.graphics.Rect; -import android.text.TextUtils; -import android.view.Gravity; -import android.view.View; -import android.widget.Toast; -public class LongClick { - private static final int ESTIMATED_TOAST_HEIGHT_DIPS = 48; - public static void setup(View view) { - view.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - return showLongClickText(view, view.getContentDescription()); - } - }); - } - - public static void setup(View view, final int textResId) { - view.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - return showLongClickText(view, view.getContext().getString(textResId)); - } - }); - } - - public static void setup(View view, final CharSequence text) { - view.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - return showLongClickText(view, text); - } - }); - } - - public static void remove(final View view) { - view.setOnLongClickListener(null); - } - - private static boolean showLongClickText(View view, CharSequence text) { - if (TextUtils.isEmpty(text)) { - return false; - } - - final int[] screenPos = new int[2]; // origin is device display - final Rect displayFrame = new Rect(); // includes decorations (e.g. status bar) - view.getLocationOnScreen(screenPos); - view.getWindowVisibleDisplayFrame(displayFrame); - - final Context context = view.getContext(); - final int viewWidth = view.getWidth(); - final int viewHeight = view.getHeight(); - final int viewCenterX = screenPos[0] + viewWidth / 2; - final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; - final int estimatedToastHeight = (int) (ESTIMATED_TOAST_HEIGHT_DIPS - * context.getResources().getDisplayMetrics().density); - - Toast longClickText = Toast.makeText(context, text, Toast.LENGTH_SHORT); - boolean showBelow = screenPos[1] < estimatedToastHeight; - if (showBelow) { - // Show below - // Offsets are after decorations (e.g. status bar) are factored in - longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, - viewCenterX - screenWidth / 2, - screenPos[1] - displayFrame.top + viewHeight); - } else { - // Show above - // Offsets are after decorations (e.g. status bar) are factored in - // NOTE: We can't use Gravity.BOTTOM because when the keyboard is up - // its height isn't factored in. - longClickText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, - viewCenterX - screenWidth / 2, - screenPos[1] - displayFrame.top - estimatedToastHeight); - } - - longClickText.show(); - return true; - } - -} -- cgit v1.2.3 From 3b95fea379ce4df09f0685463d2c2fb32446326c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 23 Oct 2015 18:26:13 +0200 Subject: decryptlist: implement key lookup (wip) --- .../keychain/ui/DecryptListFragment.java | 111 ++++++++++++++++++--- .../keychain/ui/util/KeyFormattingUtils.java | 41 ++++---- 2 files changed, 114 insertions(+), 38 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 22ef52f6d..8f36a8754 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -67,10 +67,14 @@ import org.openintents.openpgp.OpenPgpSignatureResult; import org.sufficientlysecure.keychain.BuildConfig; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.InputDataResult; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.InputDataParcel; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; // this import NEEDS to be above the ViewModel AND SubViewHolder one, or it won't compile! (as of 16.09.15) import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.StatusHolder; @@ -84,6 +88,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableHashMap; +import org.sufficientlysecure.keychain.util.Preferences; public class DecryptListFragment @@ -626,6 +631,68 @@ public class DecryptListFragment return false; } + private void lookupUnknownKey(final Uri inputUri, long unknownKeyId) { + + final ArrayList keyList; + final String keyserver; + + // search config + { + Preferences prefs = Preferences.getPreferences(getActivity()); + Preferences.CloudSearchPrefs cloudPrefs = + new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); + keyserver = cloudPrefs.keyserver; + } + + { + ParcelableKeyRing keyEntry = new ParcelableKeyRing(null, + KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null); + ArrayList selectedEntries = new ArrayList<>(); + selectedEntries.add(keyEntry); + + keyList = selectedEntries; + } + + CryptoOperationHelper.Callback callback + = new CryptoOperationHelper.Callback() { + + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(keyList, keyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + // TODO trigger new signature check + result.createNotify(getActivity()).show(); + mAdapter.setProcessingKeyLookup(inputUri, false); + } + + @Override + public void onCryptoOperationCancelled() { + mAdapter.setProcessingKeyLookup(inputUri, false); + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + result.createNotify(getActivity()).show(); + mAdapter.setProcessingKeyLookup(inputUri, false); + } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + }; + + mAdapter.setProcessingKeyLookup(inputUri, true); + + CryptoOperationHelper importOpHelper = new CryptoOperationHelper<>(2, this, callback, null); + importOpHelper.cryptoOperation(); + + } + + private void deleteFile(Activity activity, Uri uri) { // we can only ever delete a file once, if we got this far either it's gone or it will never work @@ -671,6 +738,7 @@ public class DecryptListFragment int mProgress, mMax; String mProgressMsg; OnClickListener mCancelled; + boolean mProcessingKeyLookup; ViewModel(Uri uri) { mInputUri = uri; @@ -699,6 +767,10 @@ public class DecryptListFragment mMax = max; } + void setProcessingKeyLookup(boolean processingKeyLookup) { + mProcessingKeyLookup = processingKeyLookup; + } + // Depends on inputUri only @Override public boolean equals(Object o) { @@ -765,17 +837,13 @@ public class DecryptListFragment } private void bindItemCancelled(ViewHolder holder, ViewModel model) { - if (holder.vAnimator.getDisplayedChild() != 3) { - holder.vAnimator.setDisplayedChild(3); - } + holder.vAnimator.setDisplayedChild(3); holder.vCancelledRetry.setOnClickListener(model.mCancelled); } private void bindItemProgress(ViewHolder holder, ViewModel model) { - if (holder.vAnimator.getDisplayedChild() != 0) { - holder.vAnimator.setDisplayedChild(0); - } + holder.vAnimator.setDisplayedChild(0); holder.vProgress.setProgress(model.mProgress); holder.vProgress.setMax(model.mMax); @@ -785,11 +853,10 @@ public class DecryptListFragment } private void bindItemSuccess(ViewHolder holder, final ViewModel model) { - if (holder.vAnimator.getDisplayedChild() != 1) { - holder.vAnimator.setDisplayedChild(1); - } + holder.vAnimator.setDisplayedChild(1); - KeyFormattingUtils.setStatus(getResources(), holder, model.mResult.mDecryptVerifyResult); + KeyFormattingUtils.setStatus(getResources(), holder, + model.mResult.mDecryptVerifyResult, model.mProcessingKeyLookup); int numFiles = model.mResult.getOutputUris().size(); holder.resizeFileList(numFiles, LayoutInflater.from(getActivity())); @@ -867,6 +934,13 @@ public class DecryptListFragment activity.startActivity(intent); } }); + } else { + holder.vSignatureLayout.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + lookupUnknownKey(model.mInputUri, keyId); + } + }); } } @@ -895,9 +969,7 @@ public class DecryptListFragment } private void bindItemFailure(ViewHolder holder, final ViewModel model) { - if (holder.vAnimator.getDisplayedChild() != 2) { - holder.vAnimator.setDisplayedChild(2); - } + holder.vAnimator.setDisplayedChild(2); holder.vErrorMsg.setText(model.mResult.getLog().getLast().mType.getMsgId()); @@ -953,6 +1025,13 @@ public class DecryptListFragment notifyItemChanged(pos); } + public void setProcessingKeyLookup(Uri uri, boolean processingKeyLookup) { + ViewModel newModel = new ViewModel(uri); + int pos = mDataset.indexOf(newModel); + mDataset.get(pos).setProcessingKeyLookup(processingKeyLookup); + notifyItemChanged(pos); + } + public void addResult(Uri uri, InputDataResult result) { ViewModel model = new ViewModel(uri); @@ -984,7 +1063,7 @@ public class DecryptListFragment public View vSignatureLayout; public TextView vSignatureName; public TextView vSignatureMail; - public TextView vSignatureAction; + public ViewAnimator vSignatureAction; public View vContextMenu; public TextView vErrorMsg; @@ -1027,7 +1106,7 @@ public class DecryptListFragment vSignatureLayout = itemView.findViewById(R.id.result_signature_layout); vSignatureName = (TextView) itemView.findViewById(R.id.result_signature_name); vSignatureMail= (TextView) itemView.findViewById(R.id.result_signature_email); - vSignatureAction = (TextView) itemView.findViewById(R.id.result_signature_action); + vSignatureAction = (ViewAnimator) itemView.findViewById(R.id.result_signature_action); vFileList = (LinearLayout) itemView.findViewById(R.id.file_list); for (int i = 0; i < vFileList.getChildCount(); i++) { @@ -1091,7 +1170,7 @@ public class DecryptListFragment } @Override - public TextView getSignatureAction() { + public ViewAnimator getSignatureAction() { return vSignatureAction; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 9ab0db03e..b9b837d71 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -28,6 +28,7 @@ import android.text.style.ForegroundColorSpan; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import android.widget.ViewAnimator; import org.openintents.openpgp.OpenPgpDecryptionResult; import org.openintents.openpgp.OpenPgpSignatureResult; @@ -440,14 +441,15 @@ public class KeyFormattingUtils { View getSignatureLayout(); TextView getSignatureUserName(); TextView getSignatureUserEmail(); - TextView getSignatureAction(); + ViewAnimator getSignatureAction(); boolean hasEncrypt(); } @SuppressWarnings("deprecation") // context.getDrawable is api lvl 21, need to use deprecated - public static void setStatus(Resources resources, StatusHolder holder, DecryptVerifyResult result) { + public static void setStatus(Resources resources, StatusHolder holder, DecryptVerifyResult result, + boolean processingkeyLookup) { if (holder.hasEncrypt()) { OpenPgpDecryptionResult decryptionResult = result.getDecryptionResult(); @@ -488,7 +490,7 @@ public class KeyFormattingUtils { OpenPgpSignatureResult signatureResult = result.getSignatureResult(); int sigText, sigIcon, sigColor; - int sigActionText, sigActionIcon; + int sigActionDisplayedChild; switch (signatureResult.getResult()) { @@ -500,8 +502,7 @@ public class KeyFormattingUtils { sigColor = R.color.key_flag_gray; // won't be used, but makes compiler happy - sigActionText = 0; - sigActionIcon = 0; + sigActionDisplayedChild = -1; break; } @@ -510,8 +511,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_verified_cutout_24dp; sigColor = R.color.key_flag_green; - sigActionText = R.string.decrypt_result_action_show; - sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + sigActionDisplayedChild = 0; break; } @@ -520,8 +520,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_unverified_cutout_24dp; sigColor = R.color.key_flag_orange; - sigActionText = R.string.decrypt_result_action_show; - sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + sigActionDisplayedChild = 0; break; } @@ -530,8 +529,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_revoked_cutout_24dp; sigColor = R.color.key_flag_red; - sigActionText = R.string.decrypt_result_action_show; - sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + sigActionDisplayedChild = 0; break; } @@ -540,8 +538,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_expired_cutout_24dp; sigColor = R.color.key_flag_red; - sigActionText = R.string.decrypt_result_action_show; - sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + sigActionDisplayedChild = 0; break; } @@ -550,8 +547,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_unknown_cutout_24dp; sigColor = R.color.key_flag_red; - sigActionText = R.string.decrypt_result_action_Lookup; - sigActionIcon = R.drawable.ic_file_download_grey_24dp; + sigActionDisplayedChild = 1; break; } @@ -560,8 +556,7 @@ public class KeyFormattingUtils { sigIcon = R.drawable.status_signature_invalid_cutout_24dp; sigColor = R.color.key_flag_red; - sigActionText = R.string.decrypt_result_action_show; - sigActionIcon = R.drawable.ic_vpn_key_grey_24dp; + sigActionDisplayedChild = 0; break; } @@ -572,13 +567,17 @@ public class KeyFormattingUtils { sigColor = R.color.key_flag_red; // won't be used, but makes compiler happy - sigActionText = 0; - sigActionIcon = 0; + sigActionDisplayedChild = -1; break; } } + // possibly switch out "Lookup" button for progress bar + if (sigActionDisplayedChild == 1 && processingkeyLookup) { + sigActionDisplayedChild = 2; + } + int sigColorRes = resources.getColor(sigColor); holder.getSignatureStatusIcon().setColorFilter(sigColorRes, PorterDuff.Mode.SRC_IN); holder.getSignatureStatusIcon().setImageDrawable(resources.getDrawable(sigIcon)); @@ -591,9 +590,7 @@ public class KeyFormattingUtils { holder.getSignatureLayout().setVisibility(View.VISIBLE); - holder.getSignatureAction().setText(sigActionText); - holder.getSignatureAction().setCompoundDrawablesWithIntrinsicBounds( - 0, 0, sigActionIcon, 0); + holder.getSignatureAction().setDisplayedChild(sigActionDisplayedChild); String userId = result.getSignatureResult().getPrimaryUserId(); KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); -- cgit v1.2.3 From cf51366bb7863f68989e30dba86a0d2dc1e41ce3 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 23 Oct 2015 18:49:31 +0200 Subject: decryptlist: re-decrypt after key lookup --- .../keychain/ui/DecryptListFragment.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 8f36a8754..1d2bf6b9c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -459,8 +459,9 @@ public class DecryptListFragment // un-cancel this one mCancelledInputUris.remove(uri); + mInputDataResults.remove(uri); mPendingInputUris.add(uri); - mAdapter.setCancelled(uri, null); + mAdapter.resetItemData(uri); cryptoOperation(); @@ -663,9 +664,7 @@ public class DecryptListFragment @Override public void onCryptoOperationSuccess(ImportKeyResult result) { - // TODO trigger new signature check - result.createNotify(getActivity()).show(); - mAdapter.setProcessingKeyLookup(inputUri, false); + retryUri(inputUri); } @Override @@ -747,7 +746,7 @@ public class DecryptListFragment mCancelled = null; } - void addResult(InputDataResult result) { + void setResult(InputDataResult result) { mResult = result; } @@ -1033,13 +1032,20 @@ public class DecryptListFragment } public void addResult(Uri uri, InputDataResult result) { - ViewModel model = new ViewModel(uri); int pos = mDataset.indexOf(model); model = mDataset.get(pos); + model.setResult(result); + notifyItemChanged(pos); + } - model.addResult(result); - + public void resetItemData(Uri uri) { + ViewModel model = new ViewModel(uri); + int pos = mDataset.indexOf(model); + model = mDataset.get(pos); + model.setResult(null); + model.setCancelled(null); + model.setProcessingKeyLookup(false); notifyItemChanged(pos); } -- cgit v1.2.3 From e92bd4bea919b6bf9ce9392133b59d9af4678d74 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 14 Nov 2015 17:43:52 +0100 Subject: decryptlist: some cleanup and streamlining of control flow --- .../keychain/ui/DecryptListFragment.java | 165 +++++++++++---------- 1 file changed, 84 insertions(+), 81 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index dbee564b1..737a5b3b6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -22,7 +22,6 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import android.Manifest; @@ -103,7 +102,7 @@ public class DecryptListFragment public static final String ARG_CAN_DELETE = "can_delete"; private static final int REQUEST_CODE_OUTPUT = 0x00007007; - private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 12; + private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; private ArrayList mInputUris; private HashMap mInputDataResults; @@ -215,12 +214,7 @@ public class DecryptListFragment mAdapter.add(uri); if (mCancelledInputUris.contains(uri)) { - mAdapter.setCancelled(uri, new OnClickListener() { - @Override - public void onClick(View v) { - retryUri(uri); - } - }); + mAdapter.setCancelled(uri, true); continue; } @@ -362,12 +356,7 @@ public class DecryptListFragment mCurrentInputUri = null; mCancelledInputUris.add(uri); - mAdapter.setCancelled(uri, new OnClickListener() { - @Override - public void onClick(View v) { - retryUri(uri); - } - }); + mAdapter.setCancelled(uri, true); cryptoOperation(); @@ -458,7 +447,7 @@ public class DecryptListFragment // un-cancel this one mCancelledInputUris.remove(uri); mPendingInputUris.add(uri); - mAdapter.setCancelled(uri, null); + mAdapter.setCancelled(uri, false); // check if there are any pending input uris cryptoOperation(); @@ -582,6 +571,11 @@ public class DecryptListFragment @Override public InputDataParcel createOperationInput() { + Activity activity = getActivity(); + if (activity == null) { + return null; + } + if (mCurrentInputUri == null) { if (mPendingInputUris.isEmpty()) { // nothing left to do @@ -593,95 +587,95 @@ public class DecryptListFragment Log.d(Constants.TAG, "mCurrentInputUri=" + mCurrentInputUri); - if (readPermissionGranted(mCurrentInputUri)) { - PgpDecryptVerifyInputParcel decryptInput = new PgpDecryptVerifyInputParcel() - .setAllowSymmetricDecryption(true); - return new InputDataParcel(mCurrentInputUri, decryptInput); - } else { + if ( ! checkAndRequestReadPermission(activity, mCurrentInputUri)) { return null; } + + PgpDecryptVerifyInputParcel decryptInput = new PgpDecryptVerifyInputParcel() + .setAllowSymmetricDecryption(true); + return new InputDataParcel(mCurrentInputUri, decryptInput); + } /** - * Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris + * Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris. + * + * This method returns true on Android < 6, or if permission is already granted. It + * requests the permission and returns false otherwise, taking over responsibility + * for mCurrentInputUri. * - * see - * https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html + * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html */ - private boolean readPermissionGranted(final Uri uri) { + private boolean checkAndRequestReadPermission(Activity activity, final Uri uri) { + if ( ! "file".equals(uri.getScheme())) { + return true; + } + if (Build.VERSION.SDK_INT < VERSION_CODES.M) { return true; } - if (! "file".equals(uri.getScheme())) { + + // Additional check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { return true; } - // Build check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN || - ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; - } else { - requestPermissions( - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, - MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); - - mCurrentInputUri = null; - mCancelledInputUris.add(uri); - mAdapter.setCancelled(uri, new OnClickListener() { - @Override - public void onClick(View v) { - retryUri(uri); - } - }); - return false; } + + requestPermissions( + new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, + REQUEST_PERMISSION_READ_EXTERNAL_STORAGE); + + return false; + } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, - @NonNull int[] grantResults) { - switch (requestCode) { - case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: { - if (grantResults.length > 0 - && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - - // permission granted -> retry all cancelled file uris! - for (Iterator iterator = mCancelledInputUris.iterator(); iterator.hasNext(); ) { - Uri uri = iterator.next(); - - if ("file".equals(uri.getScheme())) { - iterator.remove(); - mPendingInputUris.add(uri); - mAdapter.setCancelled(uri, null); - } - } + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { - // check if there are any pending input uris - cryptoOperation(); - } else { + if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + return; + } - // permission denied -> cancel all pending file uris - mCurrentInputUri = null; - for (final Uri uri : mPendingInputUris) { - if ("file".equals(uri.getScheme())) { - if (! mCancelledInputUris.contains(uri)) { - mCancelledInputUris.add(uri); - } - mAdapter.setCancelled(uri, new OnClickListener() { - @Override - public void onClick(View v) { - retryUri(uri); - } - }); - } - } + boolean permissionWasGranted = grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED; + + if (permissionWasGranted) { + + // permission granted -> retry all cancelled file uris + for (Uri uri : mCancelledInputUris) { + if ( ! "file".equals(uri.getScheme())) { + continue; } + mCancelledInputUris.remove(uri); + mPendingInputUris.add(uri); + mAdapter.setCancelled(uri, false); } - default: { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + } else { + + // permission denied -> cancel current, and all pending file uris + mCurrentInputUri = null; + for (final Uri uri : mPendingInputUris) { + if ( ! "file".equals(uri.getScheme())) { + continue; + } + mPendingInputUris.remove(uri); + mCancelledInputUris.add(uri); + mAdapter.setCancelled(uri, true); } + } + + // hand control flow back + cryptoOperation(); + } @Override @@ -1034,10 +1028,19 @@ public class DecryptListFragment notifyItemChanged(pos); } - public void setCancelled(Uri uri, OnClickListener retryListener) { + public void setCancelled(final Uri uri, boolean isCancelled) { ViewModel newModel = new ViewModel(uri); int pos = mDataset.indexOf(newModel); - mDataset.get(pos).setCancelled(retryListener); + if (isCancelled) { + mDataset.get(pos).setCancelled(new OnClickListener() { + @Override + public void onClick(View v) { + retryUri(uri); + } + }); + } else { + mDataset.get(pos).setCancelled(null); + } notifyItemChanged(pos); } -- cgit v1.2.3 From d263bade92c2161ad7759f471341647b4fe2d580 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 14 Nov 2015 18:28:25 +0100 Subject: decryptlist: minor cleanups and documentation --- .../keychain/ui/DecryptListFragment.java | 37 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 737a5b3b6..7db39af6f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -91,6 +91,22 @@ import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableHashMap; +/** Displays a list of decrypted inputs. + * + * This class has a complex control flow to manage its input URIs. Each URI + * which is in mInputUris is also in exactly one of mPendingInputUris, + * mCancelledInputUris, mCurrentInputUri, or a key in mInputDataResults. + * + * Processing of URIs happens using a looping approach: + * - There is always exactly one method running which works on mCurrentInputUri + * - Processing starts in cryptoOperation(), which pops a new mCurrentInputUri + * from the list of mPendingInputUris. + * - Once a mCurrentInputUri is finished processing, it should be set to null and + * control handed back to cryptoOperation() + * - Control flow can move through asynchronous calls, and resume in callbacks + * like onActivityResult() or onPermissionRequestResult(). + * + */ public class DecryptListFragment extends QueueingCryptoOperationFragment implements OnMenuItemClickListener { @@ -200,7 +216,9 @@ public class DecryptListFragment ); } - private void displayInputUris(ArrayList inputUris, ArrayList cancelledUris, + private void displayInputUris( + ArrayList inputUris, + ArrayList cancelledUris, HashMap results) { mInputUris = inputUris; @@ -213,16 +231,19 @@ public class DecryptListFragment for (final Uri uri : inputUris) { mAdapter.add(uri); - if (mCancelledInputUris.contains(uri)) { + boolean uriIsCancelled = mCancelledInputUris.contains(uri); + if (uriIsCancelled) { mAdapter.setCancelled(uri, true); continue; } - if (results != null && results.containsKey(uri)) { + boolean uriHasResult = results != null && results.containsKey(uri); + if (uriHasResult) { processResult(uri); - } else { - mPendingInputUris.add(uri); + continue; } + + mPendingInputUris.add(uri); } // check if there are any pending input uris @@ -791,8 +812,10 @@ public class DecryptListFragment return false; } ViewModel viewModel = (ViewModel) o; - return !(mInputUri != null ? !mInputUri.equals(viewModel.mInputUri) - : viewModel.mInputUri != null); + if (mInputUri == null) { + return viewModel.mInputUri == null; + } + return mInputUri.equals(viewModel.mInputUri); } // Depends on inputUri only -- cgit v1.2.3 From abfa7d743cf159a25f54ddcdc84d375c7a9df21e Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 15 Nov 2015 02:45:21 +0100 Subject: some optimizations and indexes for the main key list query --- .../main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 2735eb6b8..23c1250d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -298,7 +298,7 @@ public class KeyListFragment extends LoaderFragment } static final String ORDER = - KeyRings.HAS_ANY_SECRET + " DESC, UPPER(" + KeyRings.USER_ID + ") ASC"; + KeyRings.HAS_ANY_SECRET + " DESC, " + KeyRings.USER_ID + " COLLATE NOCASE ASC"; @Override public Loader onCreateLoader(int id, Bundle args) { -- cgit v1.2.3 From c4599798f9807c0cc692e1b08355892136ab317c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 15 Nov 2015 05:41:14 +0100 Subject: fix delete file securely method and use for delete original file --- .../keychain/ui/DecryptListFragment.java | 27 +++++----------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index c45a641e0..000de6e40 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -800,33 +800,18 @@ public class DecryptListFragment // we can only ever delete a file once, if we got this far either it's gone or it will never work mCanDelete = false; - if ("file".equals(uri.getScheme())) { - File file = new File(uri.getPath()); - if (file.delete()) { + try { + int deleted = FileHelper.deleteFileSecurely(activity, uri); + if (deleted > 0) { Notify.create(activity, R.string.file_delete_ok, Style.OK).show(); } else { Notify.create(activity, R.string.file_delete_none, Style.WARN).show(); } - return; + } catch (Exception e) { + Log.e(Constants.TAG, "exception deleting file", e); + Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show(); } - if ("content".equals(uri.getScheme())) { - try { - int deleted = activity.getContentResolver().delete(uri, null, null); - if (deleted > 0) { - Notify.create(activity, R.string.file_delete_ok, Style.OK).show(); - } else { - Notify.create(activity, R.string.file_delete_none, Style.WARN).show(); - } - } catch (Exception e) { - Log.e(Constants.TAG, "exception deleting file", e); - Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show(); - } - return; - } - - Notify.create(activity, R.string.file_delete_exception, Style.ERROR).show(); - } public class DecryptFilesAdapter extends RecyclerView.Adapter { -- cgit v1.2.3 From b5b197a9c4edde87cc36d61b13058c58520bafb0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 15 Nov 2015 20:54:29 +0100 Subject: decryptlist: fix iterators --- .../keychain/ui/DecryptListFragment.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 000de6e40..8adaa0670 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import android.Manifest; @@ -676,11 +677,13 @@ public class DecryptListFragment if (permissionWasGranted) { // permission granted -> retry all cancelled file uris - for (Uri uri : mCancelledInputUris) { + Iterator it = mCancelledInputUris.iterator(); + while (it.hasNext()) { + Uri uri = it.next(); if ( ! "file".equals(uri.getScheme())) { continue; } - mCancelledInputUris.remove(uri); + it.remove(); mPendingInputUris.add(uri); mAdapter.setCancelled(uri, false); } @@ -688,12 +691,17 @@ public class DecryptListFragment } else { // permission denied -> cancel current, and all pending file uris + mCancelledInputUris.add(mCurrentInputUri); + mAdapter.setCancelled(mCurrentInputUri, true); + mCurrentInputUri = null; - for (final Uri uri : mPendingInputUris) { + Iterator it = mPendingInputUris.iterator(); + while (it.hasNext()) { + Uri uri = it.next(); if ( ! "file".equals(uri.getScheme())) { continue; } - mPendingInputUris.remove(uri); + it.remove(); mCancelledInputUris.add(uri); mAdapter.setCancelled(uri, true); } -- cgit v1.2.3