Cache instances of KeyInfoFormatter

This commit is contained in:
Vincent Breitmoser
2018-07-04 19:39:28 +02:00
parent a975586086
commit 75cf861674
20 changed files with 214 additions and 291 deletions

View File

@@ -156,7 +156,7 @@ public class ApiPendingIntentFactory {
return createInternal(data, intent);
}
PendingIntent createSelectAuthenticationKeyIdPendingIntent(Intent data, String packageName) {
public PendingIntent createSelectAuthenticationKeyIdPendingIntent(Intent data, String packageName) {
Intent intent = new Intent(mContext, RemoteSelectAuthenticationKeyActivity.class);
intent.putExtra(RemoteSelectAuthenticationKeyActivity.EXTRA_PACKAGE_NAME, packageName);

View File

@@ -89,7 +89,7 @@ public class AppSettingsAllowedKeysListFragment extends RecyclerFragment<KeyChoi
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data, null);
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(requireContext(), data, null);
setAdapter(keyChoiceAdapter);
Set<Long> checkedIds = apiAppDao.getAllowedKeyIdsForApp(packageName);
keyChoiceAdapter.setSelectionByIds(checkedIds);

View File

@@ -123,7 +123,7 @@ public class SelectPublicKeyFragment extends RecyclerFragment<KeyChoiceAdapter>
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(data, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createMultiChoiceAdapter(requireContext(), data, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View File

@@ -116,7 +116,7 @@ public class SelectSignKeyIdListFragment extends RecyclerFragment<KeyChoiceAdapt
public void onLoadUnifiedKeyData(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createSingleClickableAdapter(data, this::onSelectKeyItemClicked, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createSingleClickableAdapter(requireContext(), data, this::onSelectKeyItemClicked, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View File

@@ -0,0 +1,109 @@
package org.sufficientlysecure.keychain.remote.ui.dialog;
import java.util.List;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.remote.ui.dialog.DialogKeyChoiceAdapter.KeyChoiceViewHolder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
class DialogKeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
private KeyInfoFormatter keyInfoFormatter;
DialogKeyChoiceAdapter(Context context, LayoutInflater layoutInflater) {
this.layoutInflater = layoutInflater;
this.keyInfoFormatter = new KeyInfoFormatter(context);
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.api_select_identity_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
void setActiveItem(Integer activeItem) {
this.activeItem = activeItem;
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
boolean hasActiveItem = activeItem != null;
boolean isActiveItem = hasActiveItem && position == activeItem;
Drawable icon = isActiveItem ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
holder.itemView.setVisibility(!hasActiveItem || isActiveItem ? View.VISIBLE : View.INVISIBLE);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawables(Drawable iconSelected, Drawable iconUnselected) {
this.iconSelected = iconSelected;
this.iconUnselected = iconUnselected;
notifyDataSetChanged();
}
class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation = (TextView) itemView.findViewById(R.id.key_list_item_creation);
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
Context context = vCreation.getContext();
keyInfoFormatter.setKeyInfo(keyInfo);
String email = keyInfo.email();
String name = keyInfo.name();
if (email != null) {
vName.setText(context.getString(R.string.use_key, email));
} else if (name != null) {
vName.setText(context.getString(R.string.use_key, name));
} else {
vName.setText(context.getString(R.string.use_key_no_name));
}
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
}

View File

@@ -63,7 +63,7 @@ class RemoteDeduplicatePresenter {
private void onLoadKeyInfos(List<UnifiedKeyInfo> data) {
if (keyChoiceAdapter == null) {
keyChoiceAdapter = KeyChoiceAdapter.createSingleChoiceAdapter(data, (keyInfo -> {
keyChoiceAdapter = KeyChoiceAdapter.createSingleChoiceAdapter(context, data, (keyInfo -> {
if (keyInfo.is_revoked()) {
return R.string.keychoice_revoked;
} else if (keyInfo.is_expired()) {

View File

@@ -40,27 +40,22 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.text.format.DateUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.mikepenz.materialdrawer.util.KeyboardUtil;
import org.openintents.ssh.authentication.SshAuthenticationApi;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.daos.ApiAppDao;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.remote.ui.RemoteSecurityTokenOperationActivity;
import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectAuthenticationKeyPresenter.RemoteSelectAuthenticationKeyView;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
@@ -203,7 +198,7 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
@NonNull
private RemoteSelectAuthenticationKeyView createMvpView(View view, LayoutInflater layoutInflater) {
final ImageView iconClientApp = view.findViewById(R.id.icon_client_app);
final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater, getResources());
final DialogKeyChoiceAdapter keyChoiceAdapter = new DialogKeyChoiceAdapter(requireContext(), layoutInflater);
keyChoiceList.setAdapter(keyChoiceAdapter);
return new RemoteSelectAuthenticationKeyView() {
@@ -231,7 +226,14 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
@Override
public void setTitleClientIcon(Drawable drawable) {
iconClientApp.setImageDrawable(drawable);
keyChoiceAdapter.setSelectionDrawable(drawable);
Resources resources = getResources();
ConstantState constantState = drawable.getConstantState();
Drawable iconSelected = constantState.newDrawable(resources);
Drawable iconUnselected = constantState.newDrawable(resources);
DrawableCompat.setTint(iconUnselected.mutate(), ResourcesCompat.getColor(resources, R.color.md_grey_300, null));
keyChoiceAdapter.setSelectionDrawables(iconSelected, iconUnselected);
}
@Override
@@ -258,92 +260,4 @@ public class RemoteSelectAuthenticationKeyActivity extends FragmentActivity {
(view, position) -> presenter.onKeyItemClick(position)));
}
}
private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private final Resources resources;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
KeyChoiceAdapter(LayoutInflater layoutInflater, Resources resources) {
this.layoutInflater = layoutInflater;
this.resources = resources;
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.authentication_key_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
Drawable icon = (activeItem != null && position == activeItem) ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawable(Drawable drawable) {
ConstantState constantState = drawable.getConstantState();
if (constantState == null) {
return;
}
iconSelected = constantState.newDrawable(resources);
iconUnselected = constantState.newDrawable(resources);
DrawableCompat.setTint(iconUnselected.mutate(), ResourcesCompat.getColor(resources, R.color.md_grey_300, null));
notifyDataSetChanged();
}
void setActiveItem(Integer newActiveItem) {
Integer prevActiveItem = this.activeItem;
this.activeItem = newActiveItem;
if (prevActiveItem != null) {
notifyItemChanged(prevActiveItem);
}
if (newActiveItem != null) {
notifyItemChanged(newActiveItem);
}
}
}
private static class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation;
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vCreation = itemView.findViewById(R.id.key_list_item_creation);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
vName.setText(keyInfo.name());
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, null);
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
}

View File

@@ -45,8 +45,6 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.text.format.DateUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
@@ -60,18 +58,17 @@ import android.widget.Toast;
import com.mikepenz.materialdrawer.util.KeyboardUtil;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
import org.sufficientlysecure.keychain.livedata.PgpKeyGenerationLiveData;
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.daos.KeyRepository;
import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectIdentityKeyPresenter.RemoteSelectIdentityKeyView;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.MainActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.AbstractCallback;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.util.KeyInfoFormatter;
import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
@@ -246,7 +243,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
@NonNull
private RemoteSelectIdentityKeyView createMvpView(final ViewGroup rootView, LayoutInflater layoutInflater) {
// final ImageView iconClientApp = rootView.findViewById(R.id.icon_client_app);
final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater);
final DialogKeyChoiceAdapter keyChoiceAdapter = new DialogKeyChoiceAdapter(requireContext(), layoutInflater);
final TextView titleText = rootView.findViewById(R.id.text_title_select_key);
final TextView addressText = rootView.findViewById(R.id.text_user_id);
final TextView autocryptHint = rootView.findViewById(R.id.key_import_autocrypt_hint);
@@ -446,91 +443,6 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
importOpHelper.cryptoOperation();
}
private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
private final LayoutInflater layoutInflater;
private List<UnifiedKeyInfo> data;
private Drawable iconUnselected;
private Drawable iconSelected;
private Integer activeItem;
KeyChoiceAdapter(LayoutInflater layoutInflater) {
this.layoutInflater = layoutInflater;
}
@NonNull
@Override
public KeyChoiceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View keyChoiceItemView = layoutInflater.inflate(R.layout.api_select_identity_item, parent, false);
return new KeyChoiceViewHolder(keyChoiceItemView);
}
void setActiveItem(Integer activeItem) {
this.activeItem = activeItem;
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(@NonNull KeyChoiceViewHolder holder, int position) {
UnifiedKeyInfo keyInfo = data.get(position);
boolean hasActiveItem = activeItem != null;
boolean isActiveItem = hasActiveItem && position == activeItem;
Drawable icon = isActiveItem ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon);
holder.itemView.setVisibility(!hasActiveItem || isActiveItem ? View.VISIBLE : View.INVISIBLE);
}
@Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
public void setData(List<UnifiedKeyInfo> data) {
this.data = data;
notifyDataSetChanged();
}
void setSelectionDrawables(Drawable iconSelected, Drawable iconUnselected) {
this.iconSelected = iconSelected;
this.iconUnselected = iconUnselected;
notifyDataSetChanged();
}
}
private static class KeyChoiceViewHolder extends RecyclerView.ViewHolder {
private final TextView vName;
private final TextView vCreation = (TextView) itemView.findViewById(R.id.key_list_item_creation);
private final ImageView vIcon;
KeyChoiceViewHolder(View itemView) {
super(itemView);
vName = itemView.findViewById(R.id.key_list_item_name);
vIcon = itemView.findViewById(R.id.key_list_item_icon);
}
void bind(UnifiedKeyInfo keyInfo, Drawable selectionIcon) {
Context context = vCreation.getContext();
String email = keyInfo.email();
String name = keyInfo.name();
if (email != null) {
vName.setText(context.getString(R.string.use_key, email));
} else if (name != null) {
vName.setText(context.getString(R.string.use_key, name));
} else {
vName.setText(context.getString(R.string.use_key_no_name));
}
KeyInfoFormatter keyInfoFormatter = new KeyInfoFormatter(itemView.getContext(), keyInfo, null);
keyInfoFormatter.formatCreationDate(vCreation);
vIcon.setImageDrawable(selectionIcon);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (importOpHelper.handleActivityResult(requestCode, resultCode, data)) {