From 53691d731548c70dc7e6c58f3577826bf9a73a37 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Wed, 1 Jun 2016 18:14:09 +0200 Subject: [PATCH 01/75] ImportKeys: Switch from ListFragment to RecyclerView This is the first step for: - use CardView for the list - improve ImportKeysListFragment --- .../keychain/ui/ImportKeysListFragment.java | 168 ++++++++---------- .../ui/adapter/ImportKeysAdapter.java | 153 ++++++++-------- .../res/layout/import_keys_list_fragment.xml | 19 ++ .../main/res/layout/import_keys_list_item.xml | 25 ++- 4 files changed, 177 insertions(+), 188 deletions(-) create mode 100644 OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 4d4219f56..f10fb6ef2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -18,10 +18,6 @@ package org.sufficientlysecure.keychain.ui; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - import android.Manifest; import android.app.Activity; import android.content.ContentResolver; @@ -31,15 +27,17 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; -import android.support.v4.app.ListFragment; +import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.ContextCompat; import android.support.v4.content.Loader; import android.support.v4.util.LongSparseArray; -import android.view.MotionEvent; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnTouchListener; -import android.widget.ListView; +import android.view.ViewGroup; +import android.widget.ProgressBar; import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; @@ -58,7 +56,11 @@ import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; -public class ImportKeysListFragment extends ListFragment implements +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ImportKeysListFragment extends Fragment implements LoaderManager.LoaderCallbacks>> { private static final String ARG_DATA_URI = "uri"; @@ -70,16 +72,18 @@ public class ImportKeysListFragment extends ListFragment implements private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; private Activity mActivity; - private ImportKeysAdapter mAdapter; private ParcelableProxy mParcelableProxy; + private ProgressBar mProgressBar; + private RecyclerView mRecyclerView; + private ImportKeysAdapter mAdapter; + private LoaderState mLoaderState; private static final int LOADER_ID_BYTES = 0; private static final int LOADER_ID_CLOUD = 1; private LongSparseArray mCachedKeyData; - private boolean mNonInteractive; private boolean mShowingOrbotDialog; @@ -206,39 +210,26 @@ public class ImportKeysListFragment extends ListFragment implements } } - /** - * Define Adapter and Loader on create of Activity - */ @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.import_keys_list_fragment, container, false); mActivity = getActivity(); - // Give some text to display if there is no data. - setEmptyText(mActivity.getString(R.string.error_nothing_import)); - - // Create an empty adapter we will use to display the loaded data. - mAdapter = new ImportKeysAdapter(mActivity); - setListAdapter(mAdapter); - Bundle args = getArguments(); Uri dataUri = args.getParcelable(ARG_DATA_URI); byte[] bytes = args.getByteArray(ARG_BYTES); String query = args.getString(ARG_SERVER_QUERY); - mNonInteractive = args.getBoolean(ARG_NON_INTERACTIVE, false); + boolean nonInteractive = args.getBoolean(ARG_NON_INTERACTIVE, false); - getListView().setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - if (!mAdapter.isEmpty()) { - mActivity.onTouchEvent(event); - } - return false; - } - }); + mProgressBar = (ProgressBar) view.findViewById(R.id.progress_view); + mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); + RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(mLayoutManager); - getListView().setFastScrollEnabled(true); + // Create an empty adapter we will use to display the loaded data. + mAdapter = new ImportKeysAdapter(mActivity, nonInteractive); + mRecyclerView.setAdapter(mAdapter); if (dataUri != null || bytes != null) { mLoaderState = new BytesLoaderState(bytes, dataUri); @@ -252,23 +243,25 @@ public class ImportKeysListFragment extends ListFragment implements mLoaderState = new CloudLoaderState(query, cloudSearchPrefs); } - if (dataUri != null && ! checkAndRequestReadPermission(dataUri)) { - return; + if (dataUri != null && !checkAndRequestReadPermission(dataUri)) { + return view; } restartLoaders(); + + return view; } /** * 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. - * + *

* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html */ private boolean checkAndRequestReadPermission(final Uri uri) { - if ( ! ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { + if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { return true; } @@ -312,30 +305,13 @@ public class ImportKeysListFragment extends ListFragment implements } } - @Override - public void onListItemClick(ListView l, View v, int position, long id) { - super.onListItemClick(l, v, position, id); - - if (mNonInteractive) { - return; - } - - // Select checkbox! - // Update underlying data and notify adapter of change. The adapter will - // update the view automatically. - - ImportKeysListEntry entry = mAdapter.getItem(position); - entry.setSelected(!entry.isSelected()); - mAdapter.notifyDataSetChanged(); - } - public void loadNew(LoaderState loaderState) { mLoaderState = loaderState; if (mLoaderState instanceof BytesLoaderState) { BytesLoaderState ls = (BytesLoaderState) mLoaderState; - if ( ls.mDataUri != null && ! checkAndRequestReadPermission(ls.mDataUri)) { + if (ls.mDataUri != null && !checkAndRequestReadPermission(ls.mDataUri)) { return; } } @@ -344,69 +320,67 @@ public class ImportKeysListFragment extends ListFragment implements } public void destroyLoader() { - if (getLoaderManager().getLoader(LOADER_ID_BYTES) != null) { - getLoaderManager().destroyLoader(LOADER_ID_BYTES); + LoaderManager loaderManager = getLoaderManager(); + + if (loaderManager.getLoader(LOADER_ID_BYTES) != null) { + loaderManager.destroyLoader(LOADER_ID_BYTES); } - if (getLoaderManager().getLoader(LOADER_ID_CLOUD) != null) { - getLoaderManager().destroyLoader(LOADER_ID_CLOUD); - } - if (getView() != null) { - setListShown(true); + if (loaderManager.getLoader(LOADER_ID_CLOUD) != null) { + loaderManager.destroyLoader(LOADER_ID_CLOUD); } } private void restartLoaders() { + LoaderManager loaderManager = getLoaderManager(); + if (mLoaderState instanceof BytesLoaderState) { - // Start out with a progress indicator. - setListShown(false); - - getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this); + loaderManager.restartLoader(LOADER_ID_BYTES, null, this); } else if (mLoaderState instanceof CloudLoaderState) { - // Start out with a progress indicator. - setListShown(false); - - getLoaderManager().restartLoader(LOADER_ID_CLOUD, null, this); + loaderManager.restartLoader(LOADER_ID_CLOUD, null, this); } } @Override - public Loader>> - onCreateLoader(int id, Bundle args) { + public Loader>> onCreateLoader( + int id, + Bundle args + ) { + + Loader>> loader; switch (id) { case LOADER_ID_BYTES: { - return new ImportKeysListLoader(mActivity, (BytesLoaderState) mLoaderState); + loader = new ImportKeysListLoader(mActivity, (BytesLoaderState) mLoaderState); + break; } case LOADER_ID_CLOUD: { CloudLoaderState ls = (CloudLoaderState) mLoaderState; - return new ImportKeysListCloudLoader(getActivity(), ls.mServerQuery, ls.mCloudPrefs, - mParcelableProxy); + loader = new ImportKeysListCloudLoader(getActivity(), ls.mServerQuery, + ls.mCloudPrefs, mParcelableProxy); + break; } - default: - return null; + loader = null; } + + if (loader != null) { + mRecyclerView.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); + } + + return loader; } @Override - public void onLoadFinished(Loader>> loader, - AsyncTaskResultWrapper> data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) + public void onLoadFinished( + Loader>> loader, + AsyncTaskResultWrapper> data + ) { - Log.d(Constants.TAG, "data: " + data.getResult()); - - // swap in the real data! mAdapter.setData(data.getResult()); mAdapter.notifyDataSetChanged(); - setListAdapter(mAdapter); - - // The list should now be shown. - if (isResumed()) { - setListShown(true); - } else { - setListShownNoAnimation(true); - } + mRecyclerView.setVisibility(View.VISIBLE); + mProgressBar.setVisibility(View.GONE); // free old cached key data mCachedKeyData = null; @@ -414,7 +388,6 @@ public class ImportKeysListFragment extends ListFragment implements GetKeyResult getKeyResult = (GetKeyResult) data.getOperationResult(); switch (loader.getId()) { case LOADER_ID_BYTES: - if (getKeyResult.success()) { // No error mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); @@ -424,7 +397,6 @@ public class ImportKeysListFragment extends ListFragment implements break; case LOADER_ID_CLOUD: - if (getKeyResult.success()) { // No error } else if (getKeyResult.isPending()) { @@ -488,11 +460,11 @@ public class ImportKeysListFragment extends ListFragment implements switch (loader.getId()) { case LOADER_ID_BYTES: // Clear the data in the adapter. - mAdapter.clear(); + mAdapter.clearData(); break; case LOADER_ID_CLOUD: // Clear the data in the adapter. - mAdapter.clear(); + mAdapter.clearData(); break; default: break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index a6d311134..360f3782f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -17,16 +17,14 @@ package org.sufficientlysecure.keychain.ui.adapter; -import android.annotation.TargetApi; -import android.app.Activity; import android.content.Context; import android.graphics.Color; -import android.os.Build; +import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -47,13 +45,18 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -public class ImportKeysAdapter extends ArrayAdapter { - protected LayoutInflater mInflater; - protected Activity mActivity; +public class ImportKeysAdapter extends RecyclerView.Adapter { - protected List mData; + private Context mContext; + private boolean mNonInteractive; + private List mData; - static class ViewHolder { + public ImportKeysAdapter(Context mContext, boolean mNonInteractive) { + this.mContext = mContext; + this.mNonInteractive = mNonInteractive; + } + + public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mainUserId; public TextView mainUserIdRest; public TextView keyId; @@ -63,38 +66,29 @@ public class ImportKeysAdapter extends ArrayAdapter { public View userIdsDivider; public LinearLayout userIdsList; public CheckBox checkBox; - } - public ImportKeysAdapter(Activity activity) { - super(activity, -1); - mActivity = activity; - mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setData(List data) { - - clear(); - if (data != null) { - this.mData = data; - - // add data to extended ArrayAdapter - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - addAll(data); - } else { - for (ImportKeysListEntry entry : data) { - add(entry); - } - } + public ViewHolder(View itemView) { + super(itemView); } } + public void clearData() { + mData = null; + notifyDataSetChanged(); + } + + public void setData(List data) { + this.mData = data; + } + public List getData() { return mData; } - /** This method returns a list of all selected entries, with public keys sorted + /** + * This method returns a list of all selected entries, with public keys sorted * before secret keys, see ImportOperation for specifics. + * * @see ImportOperation */ public ArrayList getSelectedEntries() { @@ -115,30 +109,27 @@ public class ImportKeysAdapter extends ArrayAdapter { } @Override - public boolean hasStableIds() { - return true; + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.import_keys_list_item, parent, false); + + ViewHolder vh = new ViewHolder(v); + vh.mainUserId = (TextView) v.findViewById(R.id.import_item_user_id); + vh.mainUserIdRest = (TextView) v.findViewById(R.id.import_item_user_id_email); + vh.keyId = (TextView) v.findViewById(R.id.import_item_key_id); + vh.fingerprint = (TextView) v.findViewById(R.id.import_item_fingerprint); + vh.algorithm = (TextView) v.findViewById(R.id.import_item_algorithm); + vh.status = (ImageView) v.findViewById(R.id.import_item_status); + vh.userIdsDivider = v.findViewById(R.id.import_item_status_divider); + vh.userIdsList = (LinearLayout) v.findViewById(R.id.import_item_user_ids_list); + vh.checkBox = (CheckBox) v.findViewById(R.id.import_item_selected); + + return vh; } - public View getView(int position, View convertView, ViewGroup parent) { - ImportKeysListEntry entry = mData.get(position); - Highlighter highlighter = new Highlighter(mActivity, entry.getQuery()); - ViewHolder holder; - if (convertView == null) { - holder = new ViewHolder(); - convertView = mInflater.inflate(R.layout.import_keys_list_item, null); - holder.mainUserId = (TextView) convertView.findViewById(R.id.import_item_user_id); - holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.import_item_user_id_email); - holder.keyId = (TextView) convertView.findViewById(R.id.import_item_key_id); - holder.fingerprint = (TextView) convertView.findViewById(R.id.import_item_fingerprint); - holder.algorithm = (TextView) convertView.findViewById(R.id.import_item_algorithm); - holder.status = (ImageView) convertView.findViewById(R.id.import_item_status); - holder.userIdsDivider = convertView.findViewById(R.id.import_item_status_divider); - holder.userIdsList = (LinearLayout) convertView.findViewById(R.id.import_item_user_ids_list); - holder.checkBox = (CheckBox) convertView.findViewById(R.id.import_item_selected); - convertView.setTag(holder); - } else { - holder = (ViewHolder) convertView.getTag(); - } + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + final ImportKeysListEntry entry = mData.get(position); + Highlighter highlighter = new Highlighter(mContext, entry.getQuery()); // main user id String userId = entry.getUserIds().get(0); @@ -148,8 +139,7 @@ public class ImportKeysAdapter extends ArrayAdapter { if (userIdSplit.name != null) { // show red user id if it is a secret key if (entry.isSecretKey()) { - holder.mainUserId.setText(mActivity.getString(R.string.secret_key) - + " " + userIdSplit.name); + holder.mainUserId.setText(mContext.getString(R.string.secret_key) + " " + userIdSplit.name); } else { holder.mainUserId.setText(highlighter.highlight(userIdSplit.name)); } @@ -165,7 +155,7 @@ public class ImportKeysAdapter extends ArrayAdapter { holder.mainUserIdRest.setVisibility(View.GONE); } - holder.keyId.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), entry.getKeyIdHex())); + holder.keyId.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(mContext, entry.getKeyIdHex())); // don't show full fingerprint on key import holder.fingerprint.setVisibility(View.GONE); @@ -178,9 +168,9 @@ public class ImportKeysAdapter extends ArrayAdapter { } if (entry.isRevoked()) { - KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.REVOKED, R.color.key_flag_gray); + KeyFormattingUtils.setStatusImage(mContext, holder.status, null, State.REVOKED, R.color.key_flag_gray); } else if (entry.isExpired()) { - KeyFormattingUtils.setStatusImage(getContext(), holder.status, null, State.EXPIRED, R.color.key_flag_gray); + KeyFormattingUtils.setStatusImage(mContext, holder.status, null, State.EXPIRED, R.color.key_flag_gray); } if (entry.isRevoked() || entry.isExpired()) { @@ -189,9 +179,9 @@ public class ImportKeysAdapter extends ArrayAdapter { // no more space for algorithm display holder.algorithm.setVisibility(View.GONE); - holder.mainUserId.setTextColor(getContext().getResources().getColor(R.color.key_flag_gray)); - holder.mainUserIdRest.setTextColor(getContext().getResources().getColor(R.color.key_flag_gray)); - holder.keyId.setTextColor(getContext().getResources().getColor(R.color.key_flag_gray)); + holder.mainUserId.setTextColor(mContext.getResources().getColor(R.color.key_flag_gray)); + holder.mainUserIdRest.setTextColor(mContext.getResources().getColor(R.color.key_flag_gray)); + holder.keyId.setTextColor(mContext.getResources().getColor(R.color.key_flag_gray)); } else { holder.status.setVisibility(View.GONE); holder.algorithm.setVisibility(View.VISIBLE); @@ -199,11 +189,11 @@ public class ImportKeysAdapter extends ArrayAdapter { if (entry.isSecretKey()) { holder.mainUserId.setTextColor(Color.RED); } else { - holder.mainUserId.setTextColor(FormattingUtils.getColorFromAttr(mActivity, R.attr.colorText)); + holder.mainUserId.setTextColor(FormattingUtils.getColorFromAttr(mContext, R.attr.colorText)); } - holder.mainUserIdRest.setTextColor(FormattingUtils.getColorFromAttr(mActivity, R.attr.colorText)); - holder.keyId.setTextColor(FormattingUtils.getColorFromAttr(mActivity, R.attr.colorText)); + holder.mainUserIdRest.setTextColor(FormattingUtils.getColorFromAttr(mContext, R.attr.colorText)); + holder.keyId.setTextColor(FormattingUtils.getColorFromAttr(mContext, R.attr.colorText)); } if (entry.getUserIds().size() == 1) { @@ -237,31 +227,33 @@ public class ImportKeysAdapter extends ArrayAdapter { String cUserId = pair.getKey(); HashSet cEmails = pair.getValue(); - TextView uidView = (TextView) mInflater.inflate( + LayoutInflater inflater = LayoutInflater.from(mContext); + + TextView uidView = (TextView) inflater.inflate( R.layout.import_keys_list_entry_user_id, null); uidView.setText(highlighter.highlight(cUserId)); - uidView.setPadding(0, 0, FormattingUtils.dpToPx(getContext(), 8), 0); + uidView.setPadding(0, 0, FormattingUtils.dpToPx(mContext, 8), 0); if (entry.isRevoked() || entry.isExpired()) { - uidView.setTextColor(getContext().getResources().getColor(R.color.key_flag_gray)); + uidView.setTextColor(mContext.getResources().getColor(R.color.key_flag_gray)); } else { - uidView.setTextColor(FormattingUtils.getColorFromAttr(getContext(), R.attr.colorText)); + uidView.setTextColor(FormattingUtils.getColorFromAttr(mContext, R.attr.colorText)); } holder.userIdsList.addView(uidView); for (String email : cEmails) { - TextView emailView = (TextView) mInflater.inflate( + TextView emailView = (TextView) inflater.inflate( R.layout.import_keys_list_entry_user_id, null); emailView.setPadding( - FormattingUtils.dpToPx(getContext(), 16), 0, - FormattingUtils.dpToPx(getContext(), 8), 0); + FormattingUtils.dpToPx(mContext, 16), 0, + FormattingUtils.dpToPx(mContext, 8), 0); emailView.setText(highlighter.highlight(email)); if (entry.isRevoked() || entry.isExpired()) { - emailView.setTextColor(getContext().getResources().getColor(R.color.key_flag_gray)); + emailView.setTextColor(mContext.getResources().getColor(R.color.key_flag_gray)); } else { - emailView.setTextColor(FormattingUtils.getColorFromAttr(getContext(), R.attr.colorText)); + emailView.setTextColor(FormattingUtils.getColorFromAttr(mContext, R.attr.colorText)); } holder.userIdsList.addView(emailView); @@ -270,8 +262,19 @@ public class ImportKeysAdapter extends ArrayAdapter { } holder.checkBox.setChecked(entry.isSelected()); + holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (!mNonInteractive) { + entry.setSelected(isChecked); + } + } + }); + } - return convertView; + @Override + public int getItemCount() { + return mData != null ? mData.size() : 0; } } diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml new file mode 100644 index 000000000..2f8bad47c --- /dev/null +++ b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml index e0b19b608..76b68ecea 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml @@ -1,26 +1,21 @@ + android:singleLine="true"> - + android:paddingRight="8dp" + android:paddingTop="2dp" /> + android:padding="16dp" + android:src="@drawable/status_signature_revoked_cutout_24dp" /> + android:background="?android:attr/listDivider" + android:gravity="right" /> + android:textAppearance="?android:attr/textAppearanceSmall" + android:typeface="monospace" /> From 0eceed88ff789e4f7172c5b05d0e98b53305c2b8 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Wed, 1 Jun 2016 18:32:09 +0200 Subject: [PATCH 02/75] ImportKeys: cleanup --- .../keychain/ui/ImportKeysListFragment.java | 54 ++++++++----------- .../ui/adapter/ImportKeysAdapter.java | 4 +- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index f10fb6ef2..d9cf96ed1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -28,6 +28,7 @@ import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.ContextCompat; import android.support.v4.content.Loader; @@ -71,7 +72,7 @@ public class ImportKeysListFragment extends Fragment implements private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; - private Activity mActivity; + private FragmentActivity mActivity; private ParcelableProxy mParcelableProxy; private ProgressBar mProgressBar; @@ -224,8 +225,8 @@ public class ImportKeysListFragment extends Fragment implements mProgressBar = (ProgressBar) view.findViewById(R.id.progress_view); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); - RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mActivity); - mRecyclerView.setLayoutManager(mLayoutManager); + RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(layoutManager); // Create an empty adapter we will use to display the loaded data. mAdapter = new ImportKeysAdapter(mActivity, nonInteractive); @@ -237,18 +238,16 @@ public class ImportKeysListFragment extends Fragment implements Preferences.CloudSearchPrefs cloudSearchPrefs = args.getParcelable(ARG_CLOUD_SEARCH_PREFS); if (cloudSearchPrefs == null) { - cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs(); + cloudSearchPrefs = Preferences.getPreferences(mActivity).getCloudSearchPrefs(); } mLoaderState = new CloudLoaderState(query, cloudSearchPrefs); } - if (dataUri != null && !checkAndRequestReadPermission(dataUri)) { - return view; + if (dataUri == null || checkAndRequestReadPermission(dataUri)) { + restartLoaders(); } - restartLoaders(); - return view; } @@ -270,7 +269,7 @@ public class ImportKeysListFragment extends Fragment implements return true; } - if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) + if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; } @@ -299,9 +298,9 @@ public class ImportKeysListFragment extends Fragment implements // permission granted -> load key restartLoaders(); } else { - Toast.makeText(getActivity(), R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish(); + Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); + mActivity.setResult(Activity.RESULT_CANCELED); + mActivity.finish(); } } @@ -340,13 +339,17 @@ public class ImportKeysListFragment extends Fragment implements } } + private void setLoadingStatus(boolean ready) { + mRecyclerView.setVisibility(ready ? View.VISIBLE : View.GONE); + mProgressBar.setVisibility(ready ? View.GONE : View.VISIBLE); + } + @Override public Loader>> onCreateLoader( int id, Bundle args ) { - - Loader>> loader; + Loader>> loader = null; switch (id) { case LOADER_ID_BYTES: { loader = new ImportKeysListLoader(mActivity, (BytesLoaderState) mLoaderState); @@ -354,17 +357,14 @@ public class ImportKeysListFragment extends Fragment implements } case LOADER_ID_CLOUD: { CloudLoaderState ls = (CloudLoaderState) mLoaderState; - loader = new ImportKeysListCloudLoader(getActivity(), ls.mServerQuery, + loader = new ImportKeysListCloudLoader(mActivity, ls.mServerQuery, ls.mCloudPrefs, mParcelableProxy); break; } - default: - loader = null; } if (loader != null) { - mRecyclerView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); + setLoadingStatus(false); } return loader; @@ -375,12 +375,9 @@ public class ImportKeysListFragment extends Fragment implements Loader>> loader, AsyncTaskResultWrapper> data ) { + setLoadingStatus(true); mAdapter.setData(data.getResult()); - mAdapter.notifyDataSetChanged(); - - mRecyclerView.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); // free old cached key data mCachedKeyData = null; @@ -392,7 +389,7 @@ public class ImportKeysListFragment extends Fragment implements // No error mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); } else { - getKeyResult.createNotify(getActivity()).show(); + getKeyResult.createNotify(mActivity).show(); } break; @@ -433,8 +430,7 @@ public class ImportKeysListFragment extends Fragment implements } }; - if (OrbotHelper.putOrbotInRequiredState(dialogActions, - getActivity())) { + if (OrbotHelper.putOrbotInRequiredState(dialogActions, mActivity)) { // looks like we didn't have to show the // dialog after all mShowingOrbotDialog = false; @@ -446,7 +442,7 @@ public class ImportKeysListFragment extends Fragment implements mShowingOrbotDialog = true; } } else { - getKeyResult.createNotify(getActivity()).show(); + getKeyResult.createNotify(mActivity).show(); } break; @@ -459,11 +455,7 @@ public class ImportKeysListFragment extends Fragment implements public void onLoaderReset(Loader>> loader) { switch (loader.getId()) { case LOADER_ID_BYTES: - // Clear the data in the adapter. - mAdapter.clearData(); - break; case LOADER_ID_CLOUD: - // Clear the data in the adapter. mAdapter.clearData(); break; default: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 360f3782f..95061363c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -40,6 +40,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -79,6 +80,7 @@ public class ImportKeysAdapter extends RecyclerView.Adapter data) { this.mData = data; + notifyDataSetChanged(); } public List getData() { @@ -209,7 +211,7 @@ public class ImportKeysAdapter extends RecyclerView.Adapter> mergedUserIds = entry.getMergedUserIds(); ArrayList>> sortedIds = new ArrayList>>(mergedUserIds.entrySet()); - java.util.Collections.sort(sortedIds, new java.util.Comparator>>() { + Collections.sort(sortedIds, new java.util.Comparator>>() { @Override public int compare(Map.Entry> entry1, Map.Entry> entry2) { From f52e4a8c7f6fc62da384fa53b497a42dd0e258c5 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Thu, 2 Jun 2016 00:04:21 +0200 Subject: [PATCH 03/75] ImportKeys: Use CardView for the list and change layout --- .../ui/adapter/ImportKeysAdapter.java | 24 +++--- .../res/layout/import_keys_list_fragment.xml | 4 + .../main/res/layout/import_keys_list_item.xml | 78 ++++++++----------- OpenKeychain/src/main/res/values/colors.xml | 1 + 4 files changed, 51 insertions(+), 56 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 95061363c..02e812736 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -19,12 +19,12 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; import android.graphics.Color; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -58,6 +58,8 @@ public class ImportKeysAdapter extends RecyclerView.Adapter diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml index 76b68ecea..a7d92d64b 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml @@ -1,36 +1,29 @@ - - - + android:layout_marginBottom="4dp" + android:layout_marginTop="4dp"> + android:orientation="vertical" + android:paddingBottom="24dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="24dp"> - @@ -56,39 +50,23 @@ - + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:src="@drawable/status_signature_revoked_cutout_24dp" /> - - - - - - + + android:layout_marginBottom="8dp" + android:layout_marginTop="8dp" + android:background="?android:attr/listDivider" /> + + - + diff --git a/OpenKeychain/src/main/res/values/colors.xml b/OpenKeychain/src/main/res/values/colors.xml index d9075b587..f0b40ca37 100644 --- a/OpenKeychain/src/main/res/values/colors.xml +++ b/OpenKeychain/src/main/res/values/colors.xml @@ -2,6 +2,7 @@ #7bad45 + #e5f0da #ffffff #00ffffff From 8ae245e6dfaeb911bc3b96d5bc7c324cd25e98c6 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Thu, 2 Jun 2016 01:34:29 +0200 Subject: [PATCH 04/75] ImportKeys: Use Toolbar for Import button --- .../ic_file_download_white_24dp.png | Bin 0 -> 163 bytes .../ic_file_download_white_24dp.png | Bin 0 -> 116 bytes .../ic_file_download_white_24dp.png | Bin 0 -> 157 bytes .../ic_file_download_white_24dp.png | Bin 0 -> 197 bytes .../ic_file_download_white_24dp.png | Bin 0 -> 233 bytes .../main/res/layout/import_keys_activity.xml | 54 +++++++----------- .../res/layout/import_keys_list_fragment.xml | 5 +- 7 files changed, 24 insertions(+), 35 deletions(-) create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxxhdpi/ic_file_download_white_24dp.png diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a2039c583803eab552eb2ad15248ad4f306b14 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8mZytjh{y4_Q*ZMgP~c#YJsK$U z)~(q1m-m)lF^^vy&zFBx;@>#sNTW$[{bH;=%sZG7QZ>uQBcw?@Ce|ClF7G156^ z#Rt_}Q9HRs{l8sYa>)1&$3+cMLFMTJXY2PZ*sH$V@BeR?lj;@>g(qYZ*L3k@0BvRP MboFyt=akR{0D4_J0ssI2 literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d400472fd64b0a90998ce6c5eab813b7c8eeec12 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1Yfl%)5R22v2@+fn?1dz*HZ0um z&|dF?!>nm+mvS-{o;0&fnzA@EQ^BmzWWo}eRZ9~msAiWq$nrXiF)+AFy^vQr>(2u; OhQZU-&t;ucLK6V({vp)> literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..f53cc0c62c228828d73c90f681eda0835179b0b0 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0D6i*k&kch)?FYe|&V8Fv1*n95m zR5e$DAHp{l&A!8XfIV8!#r>2YP$7e#!c^^(-Y0%@RoZ*qi`F<)`EKq{{v+@Hw5*sR zFA(}!c2Utj$B^^;IgbBnE;xI?rFh=CsojiM7+vgNGclA;TJ|n(&Igb&p00i_>zopr E0CTxJ1ONa4 literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..78aa591668242095017c9d5e96f7a9873fe1fbc8 GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawdOTemLo)8Yz3#}@pdi5FIM2@h zcsF};z`+CWBzDIKG_pEry11Auz9p#O(7?dR#KIx4z`kMCt2a+vCtcS%nf>^QsrM(T z{K~l&Yj@SA9If=c^vXIaY>wlkMR7)vg;t&u=kNuYJa3$GaHnEwp`ORgIc%D@VZ8#xa<@HhnOS1viNAnEC})a|0sJS72xJ-2)f?&QaR z?3aFfZT$|bN3Ya!ZWwgOIdJDMXyKo5=w(d|$6F^2ai?7ZNyM@uS}y1~X^1JRa37T8 i%D!pbm~%M(0r%^vOJ5j@by@-4#Ng@b=d#Wzp$Pz$!&MXj literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/layout/import_keys_activity.xml b/OpenKeychain/src/main/res/layout/import_keys_activity.xml index 6602c4b8f..8409ed94f 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_activity.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_activity.xml @@ -1,8 +1,7 @@ + android:layout_height="match_parent"> + android:visibility="gone"> - - - + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:elevation="4dp" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + android:text="@string/import_import" + android:textColor="#ffffffff" /> - + + + diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml index 8634e3728..d309a5da9 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml @@ -1,7 +1,8 @@ + android:layout_height="match_parent" + android:background="@color/md_grey_100"> From d9562461eb8584103ad08c6645ebf881d3c90357 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Thu, 2 Jun 2016 15:44:19 +0200 Subject: [PATCH 05/75] ImportKeys: Add empty list message --- OpenKeychain/build.gradle | 4 ++ .../keychain/ui/ImportKeysListFragment.java | 31 +++++----- .../main/res/layout/import_keys_activity.xml | 1 + .../res/layout/import_keys_list_fragment.xml | 56 +++++++++++++------ 4 files changed, 61 insertions(+), 31 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index d2088bba4..5475ebe48 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -287,6 +287,10 @@ android { exclude 'META-INF/NOTICE' exclude '.readme' } + + dataBinding { + enabled = true + } } task jacocoTestReport(type:JacocoReport, dependsOn: "testFdroidDebugWithTestCoverageUnitTest") { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index d9cf96ed1..113b3d9bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -22,6 +22,7 @@ import android.Manifest; import android.app.Activity; import android.content.ContentResolver; import android.content.pm.PackageManager; +import android.databinding.DataBindingUtil; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -38,11 +39,11 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ProgressBar; import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.databinding.ImportKeysListFragmentBinding; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.GetKeyResult; @@ -73,14 +74,19 @@ public class ImportKeysListFragment extends Fragment implements private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; private FragmentActivity mActivity; + private ImportKeysListFragmentBinding binding; private ParcelableProxy mParcelableProxy; - private ProgressBar mProgressBar; private RecyclerView mRecyclerView; private ImportKeysAdapter mAdapter; private LoaderState mLoaderState; + public static final int STATUS_FIRST = 0; + public static final int STATUS_LOADING = 1; + public static final int STATUS_LOADED = 2; + public static final int STATUS_EMPTY = 3; + private static final int LOADER_ID_BYTES = 0; private static final int LOADER_ID_CLOUD = 1; @@ -88,6 +94,7 @@ public class ImportKeysListFragment extends Fragment implements private boolean mShowingOrbotDialog; + public LoaderState getLoaderState() { return mLoaderState; } @@ -137,7 +144,6 @@ public class ImportKeysListFragment extends Fragment implements Log.e(Constants.TAG, "Adapter not initialized, returning empty list"); return new ArrayList<>(); } - } /** @@ -209,11 +215,14 @@ public class ImportKeysListFragment extends Fragment implements mServerQuery = serverQuery; mCloudPrefs = cloudPrefs; } + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.import_keys_list_fragment, container, false); + binding = DataBindingUtil.inflate(inflater, R.layout.import_keys_list_fragment, container, false); + binding.setStatus(STATUS_FIRST); + View view = binding.getRoot(); mActivity = getActivity(); @@ -223,7 +232,6 @@ public class ImportKeysListFragment extends Fragment implements String query = args.getString(ARG_SERVER_QUERY); boolean nonInteractive = args.getBoolean(ARG_NON_INTERACTIVE, false); - mProgressBar = (ProgressBar) view.findViewById(R.id.progress_view); mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mActivity); mRecyclerView.setLayoutManager(layoutManager); @@ -339,11 +347,6 @@ public class ImportKeysListFragment extends Fragment implements } } - private void setLoadingStatus(boolean ready) { - mRecyclerView.setVisibility(ready ? View.VISIBLE : View.GONE); - mProgressBar.setVisibility(ready ? View.GONE : View.VISIBLE); - } - @Override public Loader>> onCreateLoader( int id, @@ -364,7 +367,7 @@ public class ImportKeysListFragment extends Fragment implements } if (loader != null) { - setLoadingStatus(false); + binding.setStatus(STATUS_LOADING); } return loader; @@ -375,9 +378,9 @@ public class ImportKeysListFragment extends Fragment implements Loader>> loader, AsyncTaskResultWrapper> data ) { - setLoadingStatus(true); - - mAdapter.setData(data.getResult()); + ArrayList result = data.getResult(); + binding.setStatus(result.size() > 0 ? STATUS_LOADED : STATUS_EMPTY); + mAdapter.setData(result); // free old cached key data mCachedKeyData = null; diff --git a/OpenKeychain/src/main/res/layout/import_keys_activity.xml b/OpenKeychain/src/main/res/layout/import_keys_activity.xml index 8409ed94f..da493f1d3 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_activity.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_activity.xml @@ -65,6 +65,7 @@ android:drawablePadding="8dp" android:drawableRight="@drawable/ic_file_download_white_24dp" android:gravity="center_vertical" + android:maxLines="1" android:text="@string/import_import" android:textColor="#ffffffff" /> diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml index d309a5da9..4c816dc18 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_fragment.xml @@ -1,22 +1,44 @@ - + - + - + + + + + + + - + android:background="@color/md_grey_100"> + + + + + + + + From 96f405f5eedd41b5d194886f9994bedb87b2c566 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Thu, 16 Jun 2016 22:10:55 +0200 Subject: [PATCH 06/75] ImportKeys: Remove bottom toolbar --- .../keychain/ui/ImportKeysActivity.java | 7 ----- .../main/res/layout/import_keys_activity.xml | 31 ++----------------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 7d2d30c35..43164e55a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -25,7 +25,6 @@ import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import org.sufficientlysecure.keychain.Constants; @@ -94,12 +93,6 @@ public class ImportKeysActivity extends BaseActivity mFreshIntent = true; setFullScreenDialogClose(Activity.RESULT_CANCELED, true); - findViewById(R.id.import_import).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - importSelectedKeys(); - } - }); } @Override diff --git a/OpenKeychain/src/main/res/layout/import_keys_activity.xml b/OpenKeychain/src/main/res/layout/import_keys_activity.xml index da493f1d3..d5dd3fdce 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_activity.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_activity.xml @@ -47,35 +47,10 @@ android:layout_height="match_parent" android:layout_weight="1" /> - - - - - - - + android:layout_height="wrap_content"/> From a0f371af41677f7d5f741fd8db8ed7d341ccced2 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Fri, 17 Jun 2016 21:36:21 +0200 Subject: [PATCH 07/75] ImportKeys: Refactoring Move loader related class to a separate package --- ...reateSecurityTokenImportResetFragment.java | 3 +- .../keychain/ui/ImportKeysActivity.java | 14 ++++---- .../keychain/ui/ImportKeysCloudFragment.java | 4 +-- .../keychain/ui/ImportKeysFileFragment.java | 5 +-- .../keychain/ui/ImportKeysListFragment.java | 33 ++++--------------- .../AsyncTaskResultWrapper.java | 2 +- .../keychain/ui/loader/BytesLoaderState.java | 15 +++++++++ .../keychain/ui/loader/CloudLoaderState.java | 15 +++++++++ .../ImportKeysListCloudLoader.java | 2 +- .../ImportKeysListLoader.java | 3 +- .../keychain/ui/loader/LoaderState.java | 4 +++ 11 files changed, 56 insertions(+), 44 deletions(-) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/{adapter => loader}/AsyncTaskResultWrapper.java (96%) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/{adapter => loader}/ImportKeysListCloudLoader.java (99%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/{adapter => loader}/ImportKeysListLoader.java (97%) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java index 795d27b6c..682f63e9c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.SecurityTokenListenerFragment; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Preferences; @@ -210,7 +211,7 @@ public class CreateSecurityTokenImportResetFragment } public void refreshSearch() { - mListFragment.loadNew(new ImportKeysListFragment.CloudLoaderState("0x" + mTokenFingerprint, + mListFragment.loadNew(new CloudLoaderState("0x" + mTokenFingerprint, Preferences.getPreferences(getActivity()).getCloudSearchPrefs())); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 43164e55a..fa441692a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -37,6 +37,9 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; +import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; +import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.ui.loader.LoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; @@ -318,7 +321,7 @@ public class ImportKeysActivity extends BaseActivity } } - public void loadCallback(final ImportKeysListFragment.LoaderState loaderState) { + public void loadCallback(LoaderState loaderState) { FragmentManager fragMan = getSupportFragmentManager(); ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST); keyListFragment.loadNew(loaderState); @@ -339,8 +342,8 @@ public class ImportKeysActivity extends BaseActivity 1, this, this, R.string.progress_importing ); - ImportKeysListFragment.LoaderState ls = keyListFragment.getLoaderState(); - if (ls instanceof ImportKeysListFragment.BytesLoaderState) { + LoaderState ls = keyListFragment.getLoaderState(); + if (ls instanceof BytesLoaderState) { Log.d(Constants.TAG, "importKeys started"); // get DATA from selected key entries @@ -365,9 +368,8 @@ public class ImportKeysActivity extends BaseActivity Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR) .show((ViewGroup) findViewById(R.id.import_snackbar)); } - } else if (ls instanceof ImportKeysListFragment.CloudLoaderState) { - ImportKeysListFragment.CloudLoaderState sls = - (ImportKeysListFragment.CloudLoaderState) ls; + } else if (ls instanceof CloudLoaderState) { + CloudLoaderState sls = (CloudLoaderState) ls; // get selected key entries ArrayList keys = new ArrayList<>(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java index fb0217cda..4e9cb4a49 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java @@ -36,6 +36,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; @@ -170,8 +171,7 @@ public class ImportKeysCloudFragment extends Fragment { cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs(); } - mImportActivity.loadCallback( - new ImportKeysListFragment.CloudLoaderState(query, cloudSearchPrefs)); + mImportActivity.loadCallback(new CloudLoaderState(query, cloudSearchPrefs)); toggleKeyboard(false); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 133cf299f..6769a09b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -37,16 +37,13 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.ui.ImportKeysListFragment.BytesLoaderState; +import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; public class ImportKeysFileFragment extends Fragment { private ImportKeysActivity mImportActivity; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 113b3d9bb..91758ce91 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -48,10 +48,13 @@ import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; -import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListCloudLoader; -import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader; +import org.sufficientlysecure.keychain.ui.loader.AsyncTaskResultWrapper; +import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; +import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.ui.loader.ImportKeysListCloudLoader; +import org.sufficientlysecure.keychain.ui.loader.ImportKeysListLoader; +import org.sufficientlysecure.keychain.ui.loader.LoaderState; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableProxy; @@ -194,30 +197,6 @@ public class ImportKeysListFragment extends Fragment implements return frag; } - static public class LoaderState { - } - - static public class BytesLoaderState extends LoaderState { - public byte[] mKeyBytes; - public Uri mDataUri; - - BytesLoaderState(byte[] keyBytes, Uri dataUri) { - mKeyBytes = keyBytes; - mDataUri = dataUri; - } - } - - static public class CloudLoaderState extends LoaderState { - Preferences.CloudSearchPrefs mCloudPrefs; - String mServerQuery; - - CloudLoaderState(String serverQuery, Preferences.CloudSearchPrefs cloudPrefs) { - mServerQuery = serverQuery; - mCloudPrefs = cloudPrefs; - } - - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = DataBindingUtil.inflate(inflater, R.layout.import_keys_list_fragment, container, false); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java similarity index 96% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java index 152629ef4..65108b1d3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.adapter; +package org.sufficientlysecure.keychain.ui.loader; import org.sufficientlysecure.keychain.operations.results.OperationResult; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java new file mode 100644 index 000000000..759848e64 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java @@ -0,0 +1,15 @@ +package org.sufficientlysecure.keychain.ui.loader; + +import android.net.Uri; + +public class BytesLoaderState implements LoaderState { + + public byte[] mKeyBytes; + public Uri mDataUri; + + public BytesLoaderState(byte[] keyBytes, Uri dataUri) { + mKeyBytes = keyBytes; + mDataUri = dataUri; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java new file mode 100644 index 000000000..4014562d0 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java @@ -0,0 +1,15 @@ +package org.sufficientlysecure.keychain.ui.loader; + +import org.sufficientlysecure.keychain.util.Preferences; + +public class CloudLoaderState implements LoaderState { + + public Preferences.CloudSearchPrefs mCloudPrefs; + public String mServerQuery; + + public CloudLoaderState(String serverQuery, Preferences.CloudSearchPrefs cloudPrefs) { + mServerQuery = serverQuery; + mCloudPrefs = cloudPrefs; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java similarity index 99% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java index e77c92923..12973f314 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.adapter; +package org.sufficientlysecure.keychain.ui.loader; import android.content.Context; import android.support.annotation.Nullable; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java similarity index 97% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java index df24e9877..0d7c76bcb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.adapter; +package org.sufficientlysecure.keychain.ui.loader; import java.io.BufferedInputStream; @@ -39,7 +39,6 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogTyp import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow; -import org.sufficientlysecure.keychain.ui.ImportKeysListFragment.BytesLoaderState; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java new file mode 100644 index 000000000..d4f669790 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java @@ -0,0 +1,4 @@ +package org.sufficientlysecure.keychain.ui.loader; + +public interface LoaderState { +} From c41b658e8ffa0aab6807bca0e9a893fe8636c77c Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Fri, 17 Jun 2016 22:03:30 +0200 Subject: [PATCH 08/75] ImportKeys: Add menu in import fragments - Move cloud settings to menu - TODO: Import all keys --- .../keychain/ui/ImportKeysActivity.java | 24 +++++++------- .../keychain/ui/ImportKeysCloudFragment.java | 32 +++++++++++++------ .../keychain/ui/ImportKeysFileFragment.java | 23 +++++++++++++ .../res/layout/import_keys_cloud_fragment.xml | 29 ++++------------- .../res/menu/import_keys_cloud_fragment.xml | 8 +++++ .../res/menu/import_keys_file_fragment.xml | 8 +++++ OpenKeychain/src/main/res/values/strings.xml | 1 + 7 files changed, 82 insertions(+), 43 deletions(-) create mode 100644 OpenKeychain/src/main/res/menu/import_keys_cloud_fragment.xml create mode 100644 OpenKeychain/src/main/res/menu/import_keys_file_fragment.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index fa441692a..84844b71e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -24,6 +24,8 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.view.Menu; +import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; @@ -114,6 +116,17 @@ public class ImportKeysActivity extends BaseActivity } } + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + + // the only thing we need to take care of for restoring state is + // that the top layout is shown iff it contains a fragment + Fragment topFragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAG_TOP); + boolean hasTopFragment = topFragment != null; + findViewById(R.id.import_keys_top_layout).setVisibility(hasTopFragment ? View.VISIBLE : View.GONE); + } + protected void handleActions(@NonNull Intent intent) { String action = intent.getAction(); Bundle extras = intent.getExtras(); @@ -252,17 +265,6 @@ public class ImportKeysActivity extends BaseActivity } } - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - - // the only thing we need to take care of for restoring state is - // that the top layout is shown iff it contains a fragment - Fragment topFragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAG_TOP); - boolean hasTopFragment = topFragment != null; - findViewById(R.id.import_keys_top_layout).setVisibility(hasTopFragment ? View.VISIBLE : View.GONE); - } - /** * Shows the list of keys to be imported. * If the fragment is started with non-null bytes/dataUri/serverQuery, it will immediately diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java index 4e9cb4a49..c2e97c214 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java @@ -25,6 +25,9 @@ import android.preference.PreferenceActivity; import android.support.v4.app.Fragment; import android.view.KeyEvent; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -119,15 +122,7 @@ public class ImportKeysCloudFragment extends Fragment { } }); - View configButton = view.findViewById(R.id.cloud_import_server_config_button); - configButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(mImportActivity, SettingsActivity.class); - intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName()); - startActivity(intent); - } - }); + setHasOptionsMenu(true); return view; } @@ -162,6 +157,25 @@ public class ImportKeysCloudFragment extends Fragment { mImportActivity = (ImportKeysActivity) activity; } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.import_keys_cloud_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.import_cloud_settings: + Intent intent = new Intent(mImportActivity, SettingsActivity.class); + intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName()); + startActivity(intent); + return true; + } + + return false; + } + private void search(String query) { Preferences.CloudSearchPrefs cloudSearchPrefs = getArguments().getParcelable(ARG_CLOUD_SEARCH_PREFS); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 6769a09b0..d0138f2c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -25,10 +25,14 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceActivity; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; @@ -105,6 +109,8 @@ public class ImportKeysFileFragment extends Fragment { } }); + setHasOptionsMenu(true); + return view; } @@ -115,6 +121,23 @@ public class ImportKeysFileFragment extends Fragment { mImportActivity = (ImportKeysActivity) activity; } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.import_keys_file_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.import_all_keys: + //TODO + return true; + } + + return false; + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { diff --git a/OpenKeychain/src/main/res/layout/import_keys_cloud_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_cloud_fragment.xml index 1fc8cfdcb..6af328fd8 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_cloud_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_cloud_fragment.xml @@ -5,50 +5,33 @@ + android:orientation="horizontal" + android:paddingLeft="8dp"> + android:singleLine="true" /> - - - - + android:src="@drawable/ic_search_grey_24dp" /> diff --git a/OpenKeychain/src/main/res/menu/import_keys_cloud_fragment.xml b/OpenKeychain/src/main/res/menu/import_keys_cloud_fragment.xml new file mode 100644 index 000000000..1d78ed54a --- /dev/null +++ b/OpenKeychain/src/main/res/menu/import_keys_cloud_fragment.xml @@ -0,0 +1,8 @@ + +

+ + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/menu/import_keys_file_fragment.xml b/OpenKeychain/src/main/res/menu/import_keys_file_fragment.xml new file mode 100644 index 000000000..16dc6b555 --- /dev/null +++ b/OpenKeychain/src/main/res/menu/import_keys_file_fragment.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 21b6c09a7..289b2f4f0 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -133,6 +133,7 @@ "Confirm with phrases" "Share log" "Change password" + "Import all keys" "Add" From 155ebc4d692499ba12fa988c3a921570ca63709f Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Fri, 17 Jun 2016 22:29:15 +0200 Subject: [PATCH 09/75] ImportKeys: Add ability to import all keys in a file - Remove ability to select keys (We will add ability to import a single key) --- .../keyimport/ImportKeysListEntry.java | 18 +------------ .../keychain/ui/ImportKeysActivity.java | 8 +++--- .../keychain/ui/ImportKeysFileFragment.java | 3 +-- .../keychain/ui/ImportKeysListFragment.java | 10 +++----- .../ui/adapter/ImportKeysAdapter.java | 25 +++---------------- .../ui/loader/ImportKeysListCloudLoader.java | 1 - 6 files changed, 12 insertions(+), 53 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java index c0cc9e2a3..fc3b05c48 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java @@ -56,8 +56,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { private ArrayList mOrigins; private Integer mHashCode = null; - private boolean mSelected; - public int describeContents() { return 0; } @@ -82,7 +80,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { } dest.writeString(mAlgorithm); dest.writeByte((byte) (mSecretKey ? 1 : 0)); - dest.writeByte((byte) (mSelected ? 1 : 0)); dest.writeString(mKeybaseName); dest.writeString(mFbUsername); dest.writeStringList(mOrigins); @@ -104,7 +101,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { vr.mBitStrength = source.readInt() != 0 ? source.readInt() : null; vr.mAlgorithm = source.readString(); vr.mSecretKey = source.readByte() == 1; - vr.mSelected = source.readByte() == 1; vr.mKeybaseName = source.readString(); vr.mFbUsername = source.readString(); vr.mOrigins = new ArrayList<>(); @@ -136,14 +132,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { return mKeyIdHex; } - public boolean isSelected() { - return mSelected; - } - - public void setSelected(boolean selected) { - mSelected = selected; - } - public boolean isExpired() { return mExpired; } @@ -275,8 +263,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { public ImportKeysListEntry() { // keys from keyserver are always public keys; from keybase too mSecretKey = false; - // do not select by default - mSelected = false; + mUserIds = new ArrayList<>(); mOrigins = new ArrayList<>(); } @@ -286,9 +273,6 @@ public class ImportKeysListEntry implements Serializable, Parcelable { */ @SuppressWarnings("unchecked") public ImportKeysListEntry(Context context, UncachedKeyRing ring) { - // selected is default - this.mSelected = true; - mSecretKey = ring.isSecret(); UncachedPublicKey key = ring.getPublicKey(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 84844b71e..fd5ecf587 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -51,6 +51,7 @@ import org.sufficientlysecure.keychain.util.Preferences; import java.io.IOException; import java.util.ArrayList; +import java.util.List; public class ImportKeysActivity extends BaseActivity implements CryptoOperationHelper.Callback { @@ -329,12 +330,11 @@ public class ImportKeysActivity extends BaseActivity keyListFragment.loadNew(loaderState); } - private void importSelectedKeys() { - + public void importAllKeys() { FragmentManager fragMan = getSupportFragmentManager(); ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST); - if (keyListFragment.getSelectedEntries().size() == 0) { + if (keyListFragment.getEntries().size() == 0) { Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR) .show((ViewGroup) findViewById(R.id.import_snackbar)); return; @@ -377,7 +377,7 @@ public class ImportKeysActivity extends BaseActivity ArrayList keys = new ArrayList<>(); { // change the format into ParcelableKeyRing - ArrayList entries = keyListFragment.getSelectedEntries(); + List entries = keyListFragment.getEntries(); for (ImportKeysListEntry entry : entries) { keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername())); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index d0138f2c3..1552225b4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -25,7 +25,6 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.preference.PreferenceActivity; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; @@ -131,7 +130,7 @@ public class ImportKeysFileFragment extends Fragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.import_all_keys: - //TODO + mImportActivity.importAllKeys(); return true; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 91758ce91..797bed681 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -102,10 +102,6 @@ public class ImportKeysListFragment extends Fragment implements return mLoaderState; } - public List getData() { - return mAdapter.getData(); - } - /** * Returns an Iterator (with size) of the selected data items. * This iterator is sort of a tradeoff, it's slightly more complex than an @@ -113,7 +109,7 @@ public class ImportKeysListFragment extends Fragment implements * relevant elements on demand. */ public IteratorWithSize getSelectedData() { - final ArrayList entries = getSelectedEntries(); + final List entries = getEntries(); final Iterator it = entries.iterator(); return new IteratorWithSize() { @@ -140,9 +136,9 @@ public class ImportKeysListFragment extends Fragment implements }; } - public ArrayList getSelectedEntries() { + public List getEntries() { if (mAdapter != null) { - return mAdapter.getSelectedEntries(); + return mAdapter.getEntries(); } else { Log.e(Constants.TAG, "Adapter not initialized, returning empty list"); return new ArrayList<>(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 02e812736..4f98eb650 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -85,27 +85,21 @@ public class ImportKeysAdapter extends RecyclerView.Adapter getData() { - return mData; - } - /** * This method returns a list of all selected entries, with public keys sorted * before secret keys, see ImportOperation for specifics. * * @see ImportOperation */ - public ArrayList getSelectedEntries() { + public List getEntries() { ArrayList result = new ArrayList<>(); ArrayList secrets = new ArrayList<>(); if (mData == null) { return result; } for (ImportKeysListEntry entry : mData) { - if (entry.isSelected()) { - // add this entry to either the secret or the public list - (entry.isSecretKey() ? secrets : result).add(entry); - } + // add this entry to either the secret or the public list + (entry.isSecretKey() ? secrets : result).add(entry); } // add secret keys at the end of the list result.addAll(secrets); @@ -263,19 +257,6 @@ public class ImportKeysAdapter extends RecyclerView.Adapter Date: Fri, 17 Jun 2016 22:41:00 +0200 Subject: [PATCH 10/75] ImportKeys: Cleanup - Move loader package inside keyimport package - Change name of variables - Remove unused images --- .../loader/AsyncTaskResultWrapper.java | 2 +- .../loader/BytesLoaderState.java | 2 +- .../loader/CloudLoaderState.java | 2 +- .../loader/ImportKeysListCloudLoader.java | 2 +- .../loader/ImportKeysListLoader.java | 2 +- .../keyimport/loader/LoaderState.java | 4 +++ ...reateSecurityTokenImportResetFragment.java | 2 +- .../keychain/ui/ImportKeysActivity.java | 25 ++++++++---------- .../keychain/ui/ImportKeysCloudFragment.java | 2 +- .../keychain/ui/ImportKeysFileFragment.java | 2 +- .../keychain/ui/ImportKeysListFragment.java | 14 +++++----- .../keychain/ui/loader/LoaderState.java | 4 --- .../ic_file_download_white_24dp.png | Bin 163 -> 0 bytes .../ic_file_download_white_24dp.png | Bin 116 -> 0 bytes .../ic_file_download_white_24dp.png | Bin 157 -> 0 bytes .../ic_file_download_white_24dp.png | Bin 197 -> 0 bytes .../ic_file_download_white_24dp.png | Bin 233 -> 0 bytes OpenKeychain/src/main/res/values/colors.xml | 1 - 18 files changed, 30 insertions(+), 34 deletions(-) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/{ui => keyimport}/loader/AsyncTaskResultWrapper.java (96%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/{ui => keyimport}/loader/BytesLoaderState.java (81%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/{ui => keyimport}/loader/CloudLoaderState.java (86%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/{ui => keyimport}/loader/ImportKeysListCloudLoader.java (99%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/{ui => keyimport}/loader/ImportKeysListLoader.java (99%) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java delete mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png delete mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png delete mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png delete mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png delete mode 100644 OpenKeychain/src/main/res/drawable-xxxhdpi/ic_file_download_white_24dp.png diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java similarity index 96% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java index 65108b1d3..5adf8b686 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/AsyncTaskResultWrapper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.loader; +package org.sufficientlysecure.keychain.keyimport.loader; import org.sufficientlysecure.keychain.operations.results.OperationResult; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java similarity index 81% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java index 759848e64..909aec917 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/BytesLoaderState.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.ui.loader; +package org.sufficientlysecure.keychain.keyimport.loader; import android.net.Uri; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java similarity index 86% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java index 4014562d0..11b42eb61 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/CloudLoaderState.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.ui.loader; +package org.sufficientlysecure.keychain.keyimport.loader; import org.sufficientlysecure.keychain.util.Preferences; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java similarity index 99% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java index 991ce56a0..06db131ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListCloudLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.loader; +package org.sufficientlysecure.keychain.keyimport.loader; import android.content.Context; import android.support.annotation.Nullable; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java similarity index 99% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java index 0d7c76bcb..eb7946af1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.ui.loader; +package org.sufficientlysecure.keychain.keyimport.loader; import java.io.BufferedInputStream; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java new file mode 100644 index 000000000..9e5c6bdfc --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java @@ -0,0 +1,4 @@ +package org.sufficientlysecure.keychain.keyimport.loader; + +public interface LoaderState { +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java index 682f63e9c..4e0a8c6bd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -44,7 +44,7 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.SecurityTokenListenerFragment; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; -import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Preferences; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index fd5ecf587..906f7240d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -24,8 +24,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; -import android.view.Menu; -import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; @@ -39,9 +37,9 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; -import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; -import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; -import org.sufficientlysecure.keychain.ui.loader.LoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.LoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; @@ -349,7 +347,7 @@ public class ImportKeysActivity extends BaseActivity Log.d(Constants.TAG, "importKeys started"); // get DATA from selected key entries - IteratorWithSize selectedEntries = keyListFragment.getSelectedData(); + IteratorWithSize entries = keyListFragment.getData(); // instead of giving the entries by Intent extra, cache them into a // file to prevent Java Binder problems on heavy imports @@ -359,17 +357,16 @@ public class ImportKeysActivity extends BaseActivity // display here, we should be able to import. ParcelableFileCache cache = new ParcelableFileCache<>(this, "key_import.pcl"); - cache.writeCache(selectedEntries); - - mKeyList = null; - mKeyserver = null; - mOperationHelper.cryptoOperation(); - + cache.writeCache(entries); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR) .show((ViewGroup) findViewById(R.id.import_snackbar)); + return; } + + mKeyList = null; + mKeyserver = null; } else if (ls instanceof CloudLoaderState) { CloudLoaderState sls = (CloudLoaderState) ls; @@ -386,9 +383,9 @@ public class ImportKeysActivity extends BaseActivity mKeyList = keys; mKeyserver = sls.mCloudPrefs.keyserver; - mOperationHelper.cryptoOperation(); - } + + mOperationHelper.cryptoOperation(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java index c2e97c214..51215c946 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java @@ -39,7 +39,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 1552225b4..46c4d37e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -40,7 +40,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.FileHelper; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 797bed681..69337df4e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -49,12 +49,12 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; -import org.sufficientlysecure.keychain.ui.loader.AsyncTaskResultWrapper; -import org.sufficientlysecure.keychain.ui.loader.BytesLoaderState; -import org.sufficientlysecure.keychain.ui.loader.CloudLoaderState; -import org.sufficientlysecure.keychain.ui.loader.ImportKeysListCloudLoader; -import org.sufficientlysecure.keychain.ui.loader.ImportKeysListLoader; -import org.sufficientlysecure.keychain.ui.loader.LoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.AsyncTaskResultWrapper; +import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListCloudLoader; +import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListLoader; +import org.sufficientlysecure.keychain.keyimport.loader.LoaderState; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableProxy; @@ -108,7 +108,7 @@ public class ImportKeysListFragment extends Fragment implements * ArrayList would have been, but we save some memory by just returning * relevant elements on demand. */ - public IteratorWithSize getSelectedData() { + public IteratorWithSize getData() { final List entries = getEntries(); final Iterator it = entries.iterator(); return new IteratorWithSize() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java deleted file mode 100644 index d4f669790..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/loader/LoaderState.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.sufficientlysecure.keychain.ui.loader; - -public interface LoaderState { -} diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_file_download_white_24dp.png deleted file mode 100644 index c8a2039c583803eab552eb2ad15248ad4f306b14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8mZytjh{y4_Q*ZMgP~c#YJsK$U z)~(q1m-m)lF^^vy&zFBx;@>#sNTW$[{bH;=%sZG7QZ>uQBcw?@Ce|ClF7G156^ z#Rt_}Q9HRs{l8sYa>)1&$3+cMLFMTJXY2PZ*sH$V@BeR?lj;@>g(qYZ*L3k@0BvRP MboFyt=akR{0D4_J0ssI2 diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_file_download_white_24dp.png deleted file mode 100644 index d400472fd64b0a90998ce6c5eab813b7c8eeec12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1Yfl%)5R22v2@+fn?1dz*HZ0um z&|dF?!>nm+mvS-{o;0&fnzA@EQ^BmzWWo}eRZ9~msAiWq$nrXiF)+AFy^vQr>(2u; OhQZU-&t;ucLK6V({vp)> diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_file_download_white_24dp.png deleted file mode 100644 index f53cc0c62c228828d73c90f681eda0835179b0b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0D6i*k&kch)?FYe|&V8Fv1*n95m zR5e$DAHp{l&A!8XfIV8!#r>2YP$7e#!c^^(-Y0%@RoZ*qi`F<)`EKq{{v+@Hw5*sR zFA(}!c2Utj$B^^;IgbBnE;xI?rFh=CsojiM7+vgNGclA;TJ|n(&Igb&p00i_>zopr E0CTxJ1ONa4 diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_file_download_white_24dp.png deleted file mode 100644 index 78aa591668242095017c9d5e96f7a9873fe1fbc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhawdOTemLo)8Yz3#}@pdi5FIM2@h zcsF};z`+CWBzDIKG_pEry11Auz9p#O(7?dR#KIx4z`kMCt2a+vCtcS%nf>^QsrM(T z{K~l&Yj@SA9If=c^vXIaY>wlkMR7)vg;t&u=kNuYJa3$GaHnEwp`ORgIc%D@VZ8#xa<@HhnOS1viNAnEC})a|0sJS72xJ-2)f?&QaR z?3aFfZT$|bN3Ya!ZWwgOIdJDMXyKo5=w(d|$6F^2ai?7ZNyM@uS}y1~X^1JRa37T8 i%D!pbm~%M(0r%^vOJ5j@by@-4#Ng@b=d#Wzp$Pz$!&MXj diff --git a/OpenKeychain/src/main/res/values/colors.xml b/OpenKeychain/src/main/res/values/colors.xml index f0b40ca37..d9075b587 100644 --- a/OpenKeychain/src/main/res/values/colors.xml +++ b/OpenKeychain/src/main/res/values/colors.xml @@ -2,7 +2,6 @@ #7bad45 - #e5f0da #ffffff #00ffffff From 5e93b68b6e3bcd9cf2877bf5b1fd03ea7fa5e5a1 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Sat, 18 Jun 2016 12:14:57 +0200 Subject: [PATCH 11/75] ImportKeys: Refactoring --- .../keyimport/loader/LoaderState.java | 4 - .../AsyncTaskResultWrapper.java | 2 +- .../BytesLoaderState.java | 2 +- .../CloudLoaderState.java | 2 +- .../ImportKeysListCloudLoader.java | 2 +- .../ImportKeysListLoader.java | 2 +- .../processing/ImportKeysListener.java | 11 + .../ImportKeysOperationCallback.java | 52 +++++ .../keyimport/processing/LoaderState.java | 4 + .../remote/ui/RemoteImportKeysActivity.java | 4 +- ...reateSecurityTokenImportResetFragment.java | 12 +- .../keychain/ui/ImportKeysActivity.java | 192 +++++++----------- .../keychain/ui/ImportKeysCloudFragment.java | 20 +- .../keychain/ui/ImportKeysFileFragment.java | 42 ++-- .../keychain/ui/ImportKeysListFragment.java | 36 ++-- 15 files changed, 211 insertions(+), 176 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/{loader => processing}/AsyncTaskResultWrapper.java (96%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/{loader => processing}/BytesLoaderState.java (80%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/{loader => processing}/CloudLoaderState.java (85%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/{loader => processing}/ImportKeysListCloudLoader.java (99%) rename OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/{loader => processing}/ImportKeysListLoader.java (99%) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysOperationCallback.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/LoaderState.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java deleted file mode 100644 index 9e5c6bdfc..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/LoaderState.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.sufficientlysecure.keychain.keyimport.loader; - -public interface LoaderState { -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/AsyncTaskResultWrapper.java similarity index 96% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/AsyncTaskResultWrapper.java index 5adf8b686..3f1c9a08b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/AsyncTaskResultWrapper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/AsyncTaskResultWrapper.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.keyimport.loader; +package org.sufficientlysecure.keychain.keyimport.processing; import org.sufficientlysecure.keychain.operations.results.OperationResult; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/BytesLoaderState.java similarity index 80% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/BytesLoaderState.java index 909aec917..8330042f2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/BytesLoaderState.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/BytesLoaderState.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.keyimport.loader; +package org.sufficientlysecure.keychain.keyimport.processing; import android.net.Uri; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/CloudLoaderState.java similarity index 85% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/CloudLoaderState.java index 11b42eb61..c718a3d44 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/CloudLoaderState.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/CloudLoaderState.java @@ -1,4 +1,4 @@ -package org.sufficientlysecure.keychain.keyimport.loader; +package org.sufficientlysecure.keychain.keyimport.processing; import org.sufficientlysecure.keychain.util.Preferences; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java similarity index 99% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java index 06db131ac..c1ee9fec5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListCloudLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListCloudLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.keyimport.loader; +package org.sufficientlysecure.keychain.keyimport.processing; import android.content.Context; import android.support.annotation.Nullable; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListLoader.java similarity index 99% rename from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java rename to OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListLoader.java index eb7946af1..bba52a65e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/loader/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListLoader.java @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.sufficientlysecure.keychain.keyimport.loader; +package org.sufficientlysecure.keychain.keyimport.processing; import java.io.BufferedInputStream; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java new file mode 100644 index 000000000..499d749e6 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java @@ -0,0 +1,11 @@ +package org.sufficientlysecure.keychain.keyimport.processing; + +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; + +public interface ImportKeysListener { + + void loadKeys(LoaderState loaderState); + void importKeys(); + void handleResult(ImportKeyResult result); + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysOperationCallback.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysOperationCallback.java new file mode 100644 index 000000000..cdbe67e13 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysOperationCallback.java @@ -0,0 +1,52 @@ +package org.sufficientlysecure.keychain.keyimport.processing; + +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.service.ImportKeyringParcel; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; + +import java.util.ArrayList; + +public class ImportKeysOperationCallback implements + CryptoOperationHelper.Callback { + + private ImportKeysListener mResultListener; + private String mKeyserver; + private ArrayList mKeyList; + + public ImportKeysOperationCallback( + ImportKeysListener resultListener, + String keyserver, + ArrayList keyList + ) { + this.mResultListener = resultListener; + this.mKeyserver = keyserver; + this.mKeyList = keyList; + } + + @Override + public ImportKeyringParcel createOperationInput() { + return new ImportKeyringParcel(mKeyList, mKeyserver); + } + + @Override + public void onCryptoOperationSuccess(ImportKeyResult result) { + mResultListener.handleResult(result); + } + + @Override + public void onCryptoOperationCancelled() { + // do nothing + } + + @Override + public void onCryptoOperationError(ImportKeyResult result) { + mResultListener.handleResult(result); + } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/LoaderState.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/LoaderState.java new file mode 100644 index 000000000..dbf3e1cce --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/LoaderState.java @@ -0,0 +1,4 @@ +package org.sufficientlysecure.keychain.keyimport.processing; + +public interface LoaderState { +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteImportKeysActivity.java index ff7138231..4d8113e3c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteImportKeysActivity.java @@ -21,9 +21,7 @@ import android.content.Intent; import android.os.Bundle; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService; import org.sufficientlysecure.keychain.ui.ImportKeysActivity; -import org.sufficientlysecure.keychain.ui.SecurityTokenOperationActivity; public class RemoteImportKeysActivity extends ImportKeysActivity { @@ -39,7 +37,7 @@ public class RemoteImportKeysActivity extends ImportKeysActivity { } @Override - protected void handleResult(ImportKeyResult result) { + public void handleResult(ImportKeyResult result) { setResult(RESULT_OK, mPendingIntentData); finish(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java index 4e0a8c6bd..17baf39b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateSecurityTokenImportResetFragment.java @@ -18,10 +18,6 @@ package org.sufficientlysecure.keychain.ui; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.ArrayList; - import android.app.Activity; import android.content.Intent; import android.os.Bundle; @@ -36,6 +32,7 @@ import android.widget.TextView; import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; @@ -44,10 +41,13 @@ import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.SecurityTokenListenerFragment; import org.sufficientlysecure.keychain.ui.base.QueueingCryptoOperationFragment; -import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Preferences; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; + public class CreateSecurityTokenImportResetFragment extends QueueingCryptoOperationFragment @@ -211,7 +211,7 @@ public class CreateSecurityTokenImportResetFragment } public void refreshSearch() { - mListFragment.loadNew(new CloudLoaderState("0x" + mTokenFingerprint, + mListFragment.loadState(new CloudLoaderState("0x" + mTokenFingerprint, Preferences.getPreferences(getActivity()).getCloudSearchPrefs())); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 906f7240d..4ed1331a5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -33,26 +33,26 @@ import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; import org.sufficientlysecure.keychain.keyimport.FacebookKeyserver; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysOperationCallback; +import org.sufficientlysecure.keychain.keyimport.processing.LoaderState; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; -import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; -import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; -import org.sufficientlysecure.keychain.keyimport.loader.LoaderState; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import java.io.IOException; import java.util.ArrayList; import java.util.List; -public class ImportKeysActivity extends BaseActivity - implements CryptoOperationHelper.Callback { +public class ImportKeysActivity extends BaseActivity implements ImportKeysListener { public static final String ACTION_IMPORT_KEY = OpenKeychainIntents.IMPORT_KEY; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = OpenKeychainIntents.IMPORT_KEY_FROM_KEYSERVER; @@ -81,14 +81,10 @@ public class ImportKeysActivity extends BaseActivity public static final String TAG_FRAG_LIST = "frag_list"; public static final String TAG_FRAG_TOP = "frag_top"; - // for CryptoOperationHelper.Callback - private String mKeyserver; - private ArrayList mKeyList; + private boolean mFreshIntent; private CryptoOperationHelper mOperationHelper; - private boolean mFreshIntent; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -322,72 +318,6 @@ public class ImportKeysActivity extends BaseActivity } } - public void loadCallback(LoaderState loaderState) { - FragmentManager fragMan = getSupportFragmentManager(); - ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST); - keyListFragment.loadNew(loaderState); - } - - public void importAllKeys() { - FragmentManager fragMan = getSupportFragmentManager(); - ImportKeysListFragment keyListFragment = (ImportKeysListFragment) fragMan.findFragmentByTag(TAG_FRAG_LIST); - - if (keyListFragment.getEntries().size() == 0) { - Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR) - .show((ViewGroup) findViewById(R.id.import_snackbar)); - return; - } - - mOperationHelper = new CryptoOperationHelper<>( - 1, this, this, R.string.progress_importing - ); - - LoaderState ls = keyListFragment.getLoaderState(); - if (ls instanceof BytesLoaderState) { - Log.d(Constants.TAG, "importKeys started"); - - // get DATA from selected key entries - IteratorWithSize entries = keyListFragment.getData(); - - // instead of giving the entries by Intent extra, cache them into a - // file to prevent Java Binder problems on heavy imports - // read FileImportCache for more info. - try { - // We parcel this iteratively into a file - anything we can - // display here, we should be able to import. - ParcelableFileCache cache = - new ParcelableFileCache<>(this, "key_import.pcl"); - cache.writeCache(entries); - } catch (IOException e) { - Log.e(Constants.TAG, "Problem writing cache file", e); - Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR) - .show((ViewGroup) findViewById(R.id.import_snackbar)); - return; - } - - mKeyList = null; - mKeyserver = null; - } else if (ls instanceof CloudLoaderState) { - CloudLoaderState sls = (CloudLoaderState) ls; - - // get selected key entries - ArrayList keys = new ArrayList<>(); - { - // change the format into ParcelableKeyRing - List entries = keyListFragment.getEntries(); - for (ImportKeysListEntry entry : entries) { - keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), - entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername())); - } - } - - mKeyList = keys; - mKeyserver = sls.mCloudPrefs.keyserver; - } - - mOperationHelper.cryptoOperation(); - } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (mOperationHelper != null && @@ -397,18 +327,81 @@ public class ImportKeysActivity extends BaseActivity super.onActivityResult(requestCode, resultCode, data); } - /** - * Defines how the result of this activity is returned. - * Is overwritten in RemoteImportKeysActivity - */ - protected void handleResult(ImportKeyResult result) { + @Override + public void loadKeys(LoaderState loaderState) { + FragmentManager fM = getSupportFragmentManager(); + ImportKeysListFragment listFragment = (ImportKeysListFragment) fM.findFragmentByTag(TAG_FRAG_LIST); + + listFragment.loadState(loaderState); + } + + @Override + public void importKeys() { + FragmentManager fM = getSupportFragmentManager(); + ImportKeysListFragment listFragment = (ImportKeysListFragment) fM.findFragmentByTag(TAG_FRAG_LIST); + + if (listFragment.getEntries().size() == 0) { + Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR).show(); + return; + } + + String keyserver = null; + ArrayList keyList = null; + LoaderState loaderState = listFragment.getState(); + + Log.d(Constants.TAG, "importKeys started"); + if (loaderState instanceof BytesLoaderState) { + // get DATA from selected key entries + ParcelableFileCache.IteratorWithSize entries = listFragment.getData(); + + // instead of giving the entries by Intent extra, cache them into a + // file to prevent Java Binder problems on heavy imports + // read FileImportCache for more info. + try { + // We parcel this iteratively into a file - anything we can + // display here, we should be able to import. + ParcelableFileCache cache = new ParcelableFileCache<>(this, "key_import.pcl"); + cache.writeCache(entries); + } catch (IOException e) { + Log.e(Constants.TAG, "Problem writing cache file", e); + Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR).show(); + return; + } + + keyList = null; + keyserver = null; + } else if (loaderState instanceof CloudLoaderState) { + CloudLoaderState sls = (CloudLoaderState) loaderState; + + // get selected key entries + ArrayList keys = new ArrayList<>(); + + // change the format into ParcelableKeyRing + List entries = listFragment.getEntries(); + for (ImportKeysListEntry entry : entries) { + keys.add(new ParcelableKeyRing(entry.getFingerprintHex(), + entry.getKeyIdHex(), entry.getKeybaseName(), entry.getFbUsername())); + } + + keyList = keys; + keyserver = sls.mCloudPrefs.keyserver; + } + + ImportKeysOperationCallback callback = new ImportKeysOperationCallback(this, keyserver, keyList); + mOperationHelper = new CryptoOperationHelper(1, this, callback, R.string.progress_importing); + + mOperationHelper.cryptoOperation(); + } + + @Override + public void handleResult(ImportKeyResult result) { String intentAction = getIntent().getAction(); - if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(intentAction) - || ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(intentAction)) { + if (ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT.equals(intentAction) + || ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN.equals(intentAction)) { Intent intent = new Intent(); intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); - setResult(RESULT_OK, intent); + setResult(Activity.RESULT_OK, intent); finish(); } else if (result.isOkNew() || result.isOkUpdated()) { // User has successfully imported a key, hide first time dialog @@ -419,35 +412,8 @@ public class ImportKeysActivity extends BaseActivity intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); } else { - result.createNotify(ImportKeysActivity.this) - .show((ViewGroup) findViewById(R.id.import_snackbar)); + result.createNotify(this).show(); } } - // methods from CryptoOperationHelper.Callback - - @Override - public ImportKeyringParcel createOperationInput() { - return new ImportKeyringParcel(mKeyList, mKeyserver); - } - - @Override - public void onCryptoOperationSuccess(ImportKeyResult result) { - handleResult(result); - } - - @Override - public void onCryptoOperationCancelled() { - // do nothing - } - - @Override - public void onCryptoOperationError(ImportKeyResult result) { - handleResult(result); - } - - @Override - public boolean onCryptoSetProgress(String msg, int progress, int max) { - return false; - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java index 51215c946..425fe377f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysCloudFragment.java @@ -39,7 +39,8 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; +import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; @@ -50,11 +51,13 @@ import java.util.List; * Consists of the search bar, search button, and search settings button */ public class ImportKeysCloudFragment extends Fragment { + public static final String ARG_QUERY = "query"; public static final String ARG_DISABLE_QUERY_EDIT = "disable_query_edit"; public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs"; - private ImportKeysActivity mImportActivity; + private Activity mActivity; + private ImportKeysListener mCallback; private AutoCompleteTextView mQueryEditText; @@ -154,7 +157,14 @@ public class ImportKeysCloudFragment extends Fragment { public void onAttach(Activity activity) { super.onAttach(activity); - mImportActivity = (ImportKeysActivity) activity; + mActivity = activity; + + try { + mCallback = (ImportKeysListener) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement ImportKeysListener"); + } } @Override @@ -167,7 +177,7 @@ public class ImportKeysCloudFragment extends Fragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.import_cloud_settings: - Intent intent = new Intent(mImportActivity, SettingsActivity.class); + Intent intent = new Intent(mActivity, SettingsActivity.class); intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.CloudSearchPrefsFragment.class.getName()); startActivity(intent); return true; @@ -185,7 +195,7 @@ public class ImportKeysCloudFragment extends Fragment { cloudSearchPrefs = Preferences.getPreferences(getActivity()).getCloudSearchPrefs(); } - mImportActivity.loadCallback(new CloudLoaderState(query, cloudSearchPrefs)); + mCallback.loadKeys(new CloudLoaderState(query, cloudSearchPrefs)); toggleKeyboard(false); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 46c4d37e6..d59ae5ce2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -39,8 +39,9 @@ import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; +import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState; import org.sufficientlysecure.keychain.pgp.PgpHelper; -import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.FileHelper; @@ -49,7 +50,10 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.IOException; public class ImportKeysFileFragment extends Fragment { - private ImportKeysActivity mImportActivity; + + private Activity mActivity; + private ImportKeysListener mCallback; + private View mBrowse; private View mClipboardButton; @@ -78,7 +82,6 @@ public class ImportKeysFileFragment extends Fragment { View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false); mBrowse = view.findViewById(R.id.import_keys_file_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // open .asc or .gpg files @@ -100,10 +103,10 @@ public class ImportKeysFileFragment extends Fragment { sendText = clipboardText.toString(); sendText = PgpHelper.getPgpKeyContent(sendText); if (sendText == null) { - Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); + Notify.create(mActivity, R.string.error_bad_data, Style.ERROR).show(); return; } - mImportActivity.loadCallback(new BytesLoaderState(sendText.getBytes(), null)); + mCallback.loadKeys(new BytesLoaderState(sendText.getBytes(), null)); } } }); @@ -117,7 +120,14 @@ public class ImportKeysFileFragment extends Fragment { public void onAttach(Activity activity) { super.onAttach(activity); - mImportActivity = (ImportKeysActivity) activity; + mActivity = activity; + + try { + mCallback = (ImportKeysListener) activity; + } catch (ClassCastException e) { + throw new ClassCastException(activity.toString() + + " must implement ImportKeysListener"); + } } @Override @@ -130,7 +140,7 @@ public class ImportKeysFileFragment extends Fragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.import_all_keys: - mImportActivity.importAllKeys(); + mCallback.importKeys(); return true; } @@ -161,30 +171,30 @@ public class ImportKeysFileFragment extends Fragment { private void startImportingKeys() { boolean isEncrypted; try { - isEncrypted = FileHelper.isEncryptedFile(mImportActivity, mCurrentUri); + isEncrypted = FileHelper.isEncryptedFile(mActivity, mCurrentUri); } catch (IOException e) { Log.e(Constants.TAG, "Error opening file", e); - Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); + Notify.create(mActivity, R.string.error_bad_data, Style.ERROR).show(); return; } if (isEncrypted) { - Intent intent = new Intent(mImportActivity, DecryptActivity.class); + Intent intent = new Intent(mActivity, DecryptActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.setData(mCurrentUri); startActivity(intent); } else { - mImportActivity.loadCallback(new BytesLoaderState(null, mCurrentUri)); + mCallback.loadKeys(new BytesLoaderState(null, mCurrentUri)); } } /** * 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. - *

+ *

* see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html */ private boolean checkAndRequestReadPermission(final Uri uri) { @@ -225,9 +235,9 @@ public class ImportKeysFileFragment extends Fragment { if (permissionWasGranted) { startImportingKeys(); } else { - Toast.makeText(getActivity(), R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish(); + Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); + mActivity.setResult(Activity.RESULT_CANCELED); + mActivity.finish(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 69337df4e..c6105b18e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -46,15 +46,15 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.databinding.ImportKeysListFragmentBinding; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.keyimport.processing.AsyncTaskResultWrapper; +import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListCloudLoader; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListLoader; +import org.sufficientlysecure.keychain.keyimport.processing.LoaderState; import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; -import org.sufficientlysecure.keychain.keyimport.loader.AsyncTaskResultWrapper; -import org.sufficientlysecure.keychain.keyimport.loader.BytesLoaderState; -import org.sufficientlysecure.keychain.keyimport.loader.CloudLoaderState; -import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListCloudLoader; -import org.sufficientlysecure.keychain.keyimport.loader.ImportKeysListLoader; -import org.sufficientlysecure.keychain.keyimport.loader.LoaderState; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableProxy; @@ -77,6 +77,7 @@ public class ImportKeysListFragment extends Fragment implements private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; private FragmentActivity mActivity; + private ImportKeysListFragmentBinding binding; private ParcelableProxy mParcelableProxy; @@ -92,16 +93,10 @@ public class ImportKeysListFragment extends Fragment implements private static final int LOADER_ID_BYTES = 0; private static final int LOADER_ID_CLOUD = 1; - private LongSparseArray mCachedKeyData; private boolean mShowingOrbotDialog; - - public LoaderState getLoaderState() { - return mLoaderState; - } - /** * Returns an Iterator (with size) of the selected data items. * This iterator is sort of a tradeoff, it's slightly more complex than an @@ -287,7 +282,11 @@ public class ImportKeysListFragment extends Fragment implements } } - public void loadNew(LoaderState loaderState) { + public LoaderState getState() { + return mLoaderState; + } + + public void loadState(LoaderState loaderState) { mLoaderState = loaderState; if (mLoaderState instanceof BytesLoaderState) { @@ -301,17 +300,6 @@ public class ImportKeysListFragment extends Fragment implements restartLoaders(); } - public void destroyLoader() { - LoaderManager loaderManager = getLoaderManager(); - - if (loaderManager.getLoader(LOADER_ID_BYTES) != null) { - loaderManager.destroyLoader(LOADER_ID_BYTES); - } - if (loaderManager.getLoader(LOADER_ID_CLOUD) != null) { - loaderManager.destroyLoader(LOADER_ID_CLOUD); - } - } - private void restartLoaders() { LoaderManager loaderManager = getLoaderManager(); From 7cb13bf06ff4b8a3863b8202e54b7d3c8fafc02c Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Sun, 19 Jun 2016 17:48:41 +0200 Subject: [PATCH 12/75] ImportKeys: Extract duplicate code for permissions --- .../keychain/ui/ImportKeysFileFragment.java | 52 ++------------ .../keychain/ui/ImportKeysListFragment.java | 56 ++------------- .../keychain/ui/util/PermissionsUtil.java | 70 +++++++++++++++++++ 3 files changed, 79 insertions(+), 99 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/PermissionsUtil.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index d59ae5ce2..33d501a4e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -17,33 +17,28 @@ package org.sufficientlysecure.keychain.ui; -import android.Manifest; import android.app.Activity; -import android.content.ContentResolver; import android.content.Intent; -import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; -import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; import org.sufficientlysecure.keychain.keyimport.processing.BytesLoaderState; +import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; +import org.sufficientlysecure.keychain.ui.util.PermissionsUtil; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Log; @@ -60,7 +55,6 @@ public class ImportKeysFileFragment extends Fragment { private Uri mCurrentUri; private static final int REQUEST_CODE_FILE = 0x00007003; - private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; /** * Creates new instance of this fragment @@ -154,7 +148,7 @@ public class ImportKeysFileFragment extends Fragment { if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { mCurrentUri = data.getData(); - if (checkAndRequestReadPermission(mCurrentUri)) { + if (PermissionsUtil.checkAndRequestReadPermission(mActivity, mCurrentUri)) { startImportingKeys(); } } @@ -189,53 +183,15 @@ public class ImportKeysFileFragment extends Fragment { } } - /** - * 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. - *

- * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html - */ - private boolean checkAndRequestReadPermission(final Uri uri) { - if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { - return true; - } - - // 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.M) { - return true; - } - - if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED) { - return true; - } - - 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) { - if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - return; - } - - boolean permissionWasGranted = grantResults.length > 0 - && grantResults[0] == PackageManager.PERMISSION_GRANTED; - - if (permissionWasGranted) { + if (PermissionsUtil.checkReadPermissionResult(mActivity, requestCode, grantResults)) { startImportingKeys(); } else { - Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); mActivity.setResult(Activity.RESULT_CANCELED); mActivity.finish(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index c6105b18e..72d148550 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -18,20 +18,15 @@ package org.sufficientlysecure.keychain.ui; -import android.Manifest; import android.app.Activity; -import android.content.ContentResolver; -import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; -import android.support.v4.content.ContextCompat; import android.support.v4.content.Loader; import android.support.v4.util.LongSparseArray; import android.support.v7.widget.LinearLayoutManager; @@ -39,7 +34,6 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -55,6 +49,7 @@ import org.sufficientlysecure.keychain.keyimport.processing.LoaderState; import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; +import org.sufficientlysecure.keychain.ui.util.PermissionsUtil; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableProxy; @@ -74,8 +69,6 @@ public class ImportKeysListFragment extends Fragment implements public static final String ARG_NON_INTERACTIVE = "non_interactive"; public static final String ARG_CLOUD_SEARCH_PREFS = "cloud_search_prefs"; - private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; - private FragmentActivity mActivity; private ImportKeysListFragmentBinding binding; @@ -222,61 +215,21 @@ public class ImportKeysListFragment extends Fragment implements mLoaderState = new CloudLoaderState(query, cloudSearchPrefs); } - if (dataUri == null || checkAndRequestReadPermission(dataUri)) { + if (dataUri == null || PermissionsUtil.checkAndRequestReadPermission(mActivity, dataUri)) { restartLoaders(); } return view; } - /** - * 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. - *

- * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html - */ - private boolean checkAndRequestReadPermission(final Uri uri) { - if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { - return true; - } - - // 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.M) { - return true; - } - - if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED) { - return true; - } - - 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) { - if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - return; - } - - boolean permissionWasGranted = grantResults.length > 0 - && grantResults[0] == PackageManager.PERMISSION_GRANTED; - - if (permissionWasGranted) { - // permission granted -> load key + if (PermissionsUtil.checkReadPermissionResult(mActivity, requestCode, grantResults)) { restartLoaders(); } else { - Toast.makeText(mActivity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); mActivity.setResult(Activity.RESULT_CANCELED); mActivity.finish(); } @@ -292,7 +245,8 @@ public class ImportKeysListFragment extends Fragment implements if (mLoaderState instanceof BytesLoaderState) { BytesLoaderState ls = (BytesLoaderState) mLoaderState; - if (ls.mDataUri != null && !checkAndRequestReadPermission(ls.mDataUri)) { + if (ls.mDataUri != null && + !PermissionsUtil.checkAndRequestReadPermission(mActivity, ls.mDataUri)) { return; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/PermissionsUtil.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/PermissionsUtil.java new file mode 100644 index 000000000..14086c087 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/PermissionsUtil.java @@ -0,0 +1,70 @@ +package org.sufficientlysecure.keychain.ui.util; + +import android.Manifest; +import android.app.Activity; +import android.content.ContentResolver; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.support.v4.content.ContextCompat; +import android.widget.Toast; + +import org.sufficientlysecure.keychain.R; + +/** + * Created by Andrea on 19/06/2016. + */ +public class PermissionsUtil { + + private static final int PERMISSION_READ_EXTERNAL_STORAGE = 1; + + /** + * 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. + *

+ * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html + */ + public static boolean checkAndRequestReadPermission(Activity activity, Uri uri) { + if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { + return true; + } + + // 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.M) { + return true; + } + + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + + activity.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + PERMISSION_READ_EXTERNAL_STORAGE); + + return false; + } + + public static boolean checkReadPermissionResult(Activity activity, + int requestCode, + int[] grantResults) { + + if (requestCode != PERMISSION_READ_EXTERNAL_STORAGE) { + return false; + } + + boolean permissionWasGranted = grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED; + + if (permissionWasGranted) { + return true; + } else { + Toast.makeText(activity, R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); + + return false; + } + } + +} From db1e8b60ca082100914916f8fd9b8127df0f787e Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Tue, 28 Jun 2016 22:19:26 +0200 Subject: [PATCH 13/75] ImportKeys: Extract interface and refactoring ImportKeys: Extract interface and refactoring --- .../keychain/operations/ImportOperation.java | 39 ++++++++++--------- .../keychain/provider/ProviderHelper.java | 8 ++-- .../keychain/ui/ImportKeysActivity.java | 12 ++---- .../keychain/ui/ImportKeysListFragment.java | 2 +- .../keychain/ui/SafeSlingerActivity.java | 3 +- .../keychain/util/IteratorWithSize.java | 17 ++++++++ .../keychain/util/ParcelableFileCache.java | 8 ---- 7 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java index a20181a00..3adc38f81 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -19,20 +19,6 @@ package org.sufficientlysecure.keychain.operations; -import java.io.IOException; -import java.net.Proxy; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - import android.content.Context; import android.support.annotation.NonNull; @@ -57,13 +43,27 @@ import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; +import org.sufficientlysecure.keychain.util.IteratorWithSize; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; +import java.io.IOException; +import java.net.Proxy; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + /** * An operation class which implements high level import * operations. @@ -85,6 +85,8 @@ public class ImportOperation extends BaseOperation { public static final int MAX_THREADS = 10; + public static final String CACHE_FILE_NAME = "key_import.pcl"; + public ImportOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { super(context, providerHelper, progressable); @@ -430,15 +432,14 @@ public class ImportOperation extends BaseOperation { ImportKeyResult result; if (keyList == null) {// import from file, do serially - ParcelableFileCache cache = new ParcelableFileCache<>(mContext, - "key_import.pcl"); - + ParcelableFileCache cache = + new ParcelableFileCache<>(mContext, CACHE_FILE_NAME); result = serialKeyRingImport(cache, null, null); } else { Proxy proxy; if (cryptoInput.getParcelableProxy() == null) { // explicit proxy not set - if(!OrbotHelper.isOrbotInRequiredState(mContext)) { + if (!OrbotHelper.isOrbotInRequiredState(mContext)) { // show dialog to enable/install dialog return new ImportKeyResult(null, RequiredInputParcel.createOrbotRequiredOperation(), cryptoInput); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 6eda21d2c..7a73c1c28 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -61,9 +61,9 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.IterableIterator; +import org.sufficientlysecure.keychain.util.IteratorWithSize; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.ProgressFixedScaler; import org.sufficientlysecure.keychain.util.ProgressScaler; @@ -276,7 +276,7 @@ public class ProviderHelper { public ArrayList getConfirmedUserIds(long masterKeyId) throws NotFoundException { Cursor cursor = mContentResolver.query(UserPackets.buildUserIdsUri(masterKeyId), - new String[]{ UserPackets.USER_ID }, UserPackets.VERIFIED + " = " + Certs.VERIFIED_SECRET, null, null + new String[]{UserPackets.USER_ID}, UserPackets.VERIFIED + " = " + Certs.VERIFIED_SECRET, null, null ); if (cursor == null) { throw new NotFoundException("Key id for requested user ids not found"); @@ -476,7 +476,7 @@ public class ProviderHelper { String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId); UserPacketItem item = new UserPacketItem(); uids.add(item); - OpenPgpUtils.UserId splitUserId = KeyRing.splitUserId(userId); + OpenPgpUtils.UserId splitUserId = KeyRing.splitUserId(userId); item.userId = userId; item.name = splitUserId.name; item.email = splitUserId.email; @@ -794,7 +794,7 @@ public class ProviderHelper { } // if one is *trusted* but the other isn't, that one comes first // this overrides the primary attribute, even! - if ( (trustedCerts.size() == 0) != (o.trustedCerts.size() == 0) ) { + if ((trustedCerts.size() == 0) != (o.trustedCerts.size() == 0)) { return trustedCerts.size() > o.trustedCerts.size() ? -1 : 1; } // if one key is primary but the other isn't, the primary one always comes first diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 4ed1331a5..beac04dec 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -38,6 +38,7 @@ import org.sufficientlysecure.keychain.keyimport.processing.CloudLoaderState; import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysListener; import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysOperationCallback; import org.sufficientlysecure.keychain.keyimport.processing.LoaderState; +import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.ImportKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; @@ -351,25 +352,20 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen Log.d(Constants.TAG, "importKeys started"); if (loaderState instanceof BytesLoaderState) { - // get DATA from selected key entries - ParcelableFileCache.IteratorWithSize entries = listFragment.getData(); - // instead of giving the entries by Intent extra, cache them into a // file to prevent Java Binder problems on heavy imports // read FileImportCache for more info. try { // We parcel this iteratively into a file - anything we can // display here, we should be able to import. - ParcelableFileCache cache = new ParcelableFileCache<>(this, "key_import.pcl"); - cache.writeCache(entries); + ParcelableFileCache cache = + new ParcelableFileCache<>(this, ImportOperation.CACHE_FILE_NAME); + cache.writeCache(listFragment.getData()); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR).show(); return; } - - keyList = null; - keyserver = null; } else if (loaderState instanceof CloudLoaderState) { CloudLoaderState sls = (CloudLoaderState) loaderState; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 72d148550..cfe9bf1ca 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -50,8 +50,8 @@ import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysAdapter; import org.sufficientlysecure.keychain.ui.util.PermissionsUtil; +import org.sufficientlysecure.keychain.util.IteratorWithSize; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index 534dbfd05..e23813ac5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -30,6 +30,7 @@ import android.widget.NumberPicker; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -141,7 +142,7 @@ public class SafeSlingerActivity extends BaseActivity // We parcel this iteratively into a file - anything we can // display here, we should be able to import. ParcelableFileCache cache = - new ParcelableFileCache<>(this, "key_import.pcl"); + new ParcelableFileCache<>(this, ImportOperation.CACHE_FILE_NAME); cache.writeCache(it.size(), it.iterator()); mOperationHelper = diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java new file mode 100644 index 000000000..96cf5a47e --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/IteratorWithSize.java @@ -0,0 +1,17 @@ +package org.sufficientlysecure.keychain.util; + +import java.util.Iterator; + +/** + * An extended iterator interface, which knows the total number of its entries beforehand. + */ +public interface IteratorWithSize extends Iterator { + + /** + * Returns the total number of entries in this iterator. + * + * @return the number of entries in this iterator. + */ + int getSize(); + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java index eabbf83b8..511e1047a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java @@ -216,12 +216,4 @@ public class ParcelableFileCache { return tempFile.delete(); } - /** As the name implies, this is an extended iterator interface, which - * knows the total number of its entries beforehand. - */ - public static interface IteratorWithSize extends Iterator { - /** Returns the number of total entries in this iterator. */ - int getSize(); - } - } From 5858257babe16a9e398bfdfa939a4821244dc43a Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Tue, 28 Jun 2016 22:49:32 +0200 Subject: [PATCH 14/75] ImportKeys: Add method for single import --- .../processing/ImportKeysListener.java | 5 ++ .../keychain/ui/ImportKeysActivity.java | 36 ++++++++++++ .../keychain/util/ParcelableFileCache.java | 57 ++++++++++++------- 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java index 499d749e6..c4228c4de 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/processing/ImportKeysListener.java @@ -1,11 +1,16 @@ package org.sufficientlysecure.keychain.keyimport.processing; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; public interface ImportKeysListener { void loadKeys(LoaderState loaderState); + + void importKey(ParcelableKeyRing keyRing); + void importKeys(); + void handleResult(ImportKeyResult result); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index beac04dec..c11b116cf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -336,6 +336,41 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen listFragment.loadState(loaderState); } + @Override + public void importKey(ParcelableKeyRing keyRing) { + FragmentManager fM = getSupportFragmentManager(); + ImportKeysListFragment listFragment = (ImportKeysListFragment) fM.findFragmentByTag(TAG_FRAG_LIST); + + String keyserver = null; + ArrayList keyList = null; + LoaderState loaderState = listFragment.getState(); + + Log.d(Constants.TAG, "importKey started"); + if (loaderState instanceof BytesLoaderState) { + // instead of giving the entries by Intent extra, cache them into a + // file to prevent Java Binder problems on heavy imports + // read FileImportCache for more info. + try { + // We parcel this iteratively into a file - anything we can + // display here, we should be able to import. + ParcelableFileCache cache = + new ParcelableFileCache<>(this, ImportOperation.CACHE_FILE_NAME); + cache.writeCache(keyRing); + } catch (IOException e) { + Log.e(Constants.TAG, "Problem writing cache file", e); + Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR).show(); + return; + } + } else if (loaderState instanceof CloudLoaderState) { + //TODO + } + + ImportKeysOperationCallback callback = new ImportKeysOperationCallback(this, keyserver, keyList); + mOperationHelper = new CryptoOperationHelper(1, this, callback, R.string.progress_importing); + + mOperationHelper.cryptoOperation(); + } + @Override public void importKeys() { FragmentManager fM = getSupportFragmentManager(); @@ -367,6 +402,7 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen return; } } else if (loaderState instanceof CloudLoaderState) { + //TODO This need to be removed because it makes no sense to import "all" from cloud CloudLoaderState sls = (CloudLoaderState) loaderState; // get selected key entries diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java index 511e1047a..2ad309429 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java @@ -57,7 +57,39 @@ public class ParcelableFileCache { } public void writeCache(int numEntries, Iterator it) throws IOException { + DataOutputStream oos = getOutputStream(); + try { + oos.writeInt(numEntries); + while (it.hasNext()) { + writeParcelable(it.next(), oos); + } + } finally { + oos.close(); + } + } + + public void writeCache(E obj) throws IOException { + DataOutputStream oos = getOutputStream(); + + try { + oos.writeInt(1); + writeParcelable(obj, oos); + } finally { + oos.close(); + } + } + + private void writeParcelable(E obj, DataOutputStream oos) throws IOException { + Parcel p = Parcel.obtain(); // creating empty parcel object + p.writeParcelable(obj, 0); // saving bundle as parcel + byte[] buf = p.marshall(); + oos.writeInt(buf.length); + oos.write(buf); + p.recycle(); + } + + private DataOutputStream getOutputStream() throws IOException { File cacheDir = mContext.getCacheDir(); if (cacheDir == null) { // https://groups.google.com/forum/#!topic/android-developers/-694j87eXVU @@ -65,29 +97,12 @@ public class ParcelableFileCache { } File tempFile = new File(mContext.getCacheDir(), mFilename); - - - DataOutputStream oos = new DataOutputStream(new FileOutputStream(tempFile)); - - try { - oos.writeInt(numEntries); - - while (it.hasNext()) { - Parcel p = Parcel.obtain(); // creating empty parcel object - p.writeParcelable(it.next(), 0); // saving bundle as parcel - byte[] buf = p.marshall(); - oos.writeInt(buf.length); - oos.write(buf); - p.recycle(); - } - } finally { - oos.close(); - } - + return new DataOutputStream(new FileOutputStream(tempFile)); } /** * Reads from cache file and deletes it afterward. Convenience function for readCache(boolean). + * * @return an IteratorWithSize object containing entries read from the cache file * @throws IOException */ @@ -97,10 +112,11 @@ public class ParcelableFileCache { /** * Reads entries from a cache file and returns an IteratorWithSize object containing the entries + * * @param deleteAfterRead if true, the cache file will be deleted after being read * @return an IteratorWithSize object containing entries read from the cache file * @throws IOException if cache directory/parcel import file does not exist, or a read error - * occurs + * occurs */ public IteratorWithSize readCache(final boolean deleteAfterRead) throws IOException { @@ -205,7 +221,6 @@ public class ParcelableFileCache { } public boolean delete() throws IOException { - File cacheDir = mContext.getCacheDir(); if (cacheDir == null) { // https://groups.google.com/forum/#!topic/android-developers/-694j87eXVU From 40d6d1f750e1efe86650f3f411cbd7fba4c00cb4 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Tue, 28 Jun 2016 23:18:09 +0200 Subject: [PATCH 15/75] ImportKeys: Add import button to cards - Adapt things to material design --- .../main/res/layout/import_keys_list_item.xml | 179 ++++++++++-------- 1 file changed, 102 insertions(+), 77 deletions(-) diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml index a7d92d64b..79a39879f 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_item.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_item.xml @@ -1,94 +1,119 @@ + android:layout_marginTop="4dp" + card_view:cardCornerRadius="2dp"> - - - - - - - - - - - - - - - - - - + android:orientation="vertical"> - - + android:orientation="vertical" + android:paddingBottom="16dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="24dp"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + android:padding="8dp"> + +