mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-30 22:05:19 +00:00
set and pick from multiple passwords per app
This commit is contained in:
@@ -4,6 +4,7 @@ import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
@@ -12,15 +13,20 @@ import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.zeapo.pwdstore.PasswordStore;
|
||||
import com.zeapo.pwdstore.R;
|
||||
|
||||
public class AutofillFragment extends DialogFragment {
|
||||
private static final int MATCH_WITH = 777;
|
||||
ArrayAdapter<String> adapter;
|
||||
|
||||
public AutofillFragment() {
|
||||
}
|
||||
@@ -47,6 +53,27 @@ public class AutofillFragment extends DialogFragment {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// set up the listview now for items added by button/from preferences
|
||||
adapter = new ArrayAdapter<String>(getActivity().getApplicationContext()
|
||||
, android.R.layout.simple_list_item_1, android.R.id.text1) {
|
||||
// set text color to black because default is white...
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextView textView = (TextView) super.getView(position, convertView, parent);
|
||||
textView.setTextColor(ContextCompat.getColor(getContext(), R.color.grey_black_1000));
|
||||
return textView;
|
||||
}
|
||||
};
|
||||
((ListView) view.findViewById(R.id.matched)).setAdapter(adapter);
|
||||
// delete items by clicking them
|
||||
((ListView) view.findViewById(R.id.matched)).setOnItemClickListener(
|
||||
new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
adapter.remove(adapter.getItem(position));
|
||||
}
|
||||
});
|
||||
|
||||
SharedPreferences prefs
|
||||
= getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
|
||||
String preference = prefs.getString(packageName, "");
|
||||
@@ -62,9 +89,11 @@ public class AutofillFragment extends DialogFragment {
|
||||
break;
|
||||
default:
|
||||
((RadioButton) view.findViewById(R.id.match)).toggle();
|
||||
((EditText) view.findViewById(R.id.matched)).setText(preference);
|
||||
// trim to remove the last blank element
|
||||
adapter.addAll(preference.trim().split("\n"));
|
||||
}
|
||||
|
||||
// add items with the + button
|
||||
View.OnClickListener matchPassword = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -74,8 +103,7 @@ public class AutofillFragment extends DialogFragment {
|
||||
startActivityForResult(intent, MATCH_WITH);
|
||||
}
|
||||
};
|
||||
view.findViewById(R.id.match).setOnClickListener(matchPassword);
|
||||
view.findViewById(R.id.matched).setOnClickListener(matchPassword);
|
||||
view.findViewById(R.id.matchButton).setOnClickListener(matchPassword);
|
||||
|
||||
final SharedPreferences.Editor editor = prefs.edit();
|
||||
builder.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
|
||||
@@ -93,9 +121,14 @@ public class AutofillFragment extends DialogFragment {
|
||||
editor.putString(packageName, "/never");
|
||||
break;
|
||||
default:
|
||||
EditText matched = (EditText) view.findViewById(R.id.matched);
|
||||
String path = matched.getText().toString();
|
||||
editor.putString(packageName, path);
|
||||
StringBuilder paths = new StringBuilder();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
paths.append(adapter.getItem(i));
|
||||
if (i != adapter.getCount()) {
|
||||
paths.append("\n");
|
||||
}
|
||||
}
|
||||
editor.putString(packageName, paths.toString());
|
||||
}
|
||||
editor.apply();
|
||||
|
||||
@@ -113,9 +146,7 @@ public class AutofillFragment extends DialogFragment {
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
((EditText) getDialog().findViewById(R.id.matched)).setText(data.getStringExtra("path"));
|
||||
} else {
|
||||
((RadioButton) getDialog().findViewById(R.id.use_default)).toggle();
|
||||
adapter.add(data.getStringExtra("path"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -110,7 +110,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
|
||||
holder.secondary.setText(R.string.autofill_apps_never);
|
||||
break;
|
||||
default:
|
||||
holder.secondary.setText("Match with " + preference);
|
||||
holder.secondary.setText("Match with " + preference.split("\n")[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -44,6 +44,7 @@ public class AutofillService extends AccessibilityService {
|
||||
private SharedPreferences settings;
|
||||
private AccessibilityNodeInfo info; // the original source of the event (the edittext field)
|
||||
private ArrayList<File> items; // password choices
|
||||
private int lastWhichItem;
|
||||
private AlertDialog dialog;
|
||||
private AccessibilityWindowInfo window;
|
||||
private static Intent resultData = null; // need the intent which contains results from user interaction
|
||||
@@ -199,9 +200,14 @@ public class AutofillService extends AccessibilityService {
|
||||
if (!PasswordRepository.isInitialized()) {
|
||||
PasswordRepository.initialize(this);
|
||||
}
|
||||
String path = PasswordRepository.getWorkTree() + "/" + preference + ".gpg";
|
||||
String preferred[] = preference.split("\n");
|
||||
items = new ArrayList<>();
|
||||
items.add(new File(path));
|
||||
for (String prefer : preferred) {
|
||||
String path = PasswordRepository.getWorkTree() + "/" + prefer + ".gpg";
|
||||
if (new File(path).exists()) {
|
||||
items.add(new File(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,12 +243,12 @@ public class AutofillService extends AccessibilityService {
|
||||
dialog = null;
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(R.string.autofill_fill, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
bindDecryptAndVerify();
|
||||
}
|
||||
});
|
||||
// builder.setPositiveButton(R.string.autofill_fill, new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// bindDecryptAndVerify();
|
||||
// }
|
||||
// });
|
||||
builder.setNeutralButton("Settings", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) { //TODO make icon? gear?
|
||||
@@ -254,13 +260,34 @@ public class AutofillService extends AccessibilityService {
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
CharSequence itemNames[] = new CharSequence[items.size()];
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
itemNames[i] = items.get(i).getName().replace(".gpg", "");
|
||||
}
|
||||
|
||||
builder.setItems(itemNames, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == items.size()) {
|
||||
// the user will have to return to the app themselves.
|
||||
Intent intent = new Intent(AutofillService.this, AutofillPreferenceActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
intent.putExtra("packageName", info.getPackageName());
|
||||
intent.putExtra("appName", appName);
|
||||
startActivity(intent);
|
||||
} else {
|
||||
lastWhichItem = which;
|
||||
bindDecryptAndVerify();
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog = builder.create();
|
||||
dialog.setIcon(R.drawable.ic_launcher);
|
||||
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
|
||||
dialog.getWindow().setLayout(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
dialog.setTitle(items.get(0).getName().replace(".gpg", ""));
|
||||
// TODO size dialog
|
||||
dialog.getWindow().setLayout(WindowManager.LayoutParams.WRAP_CONTENT
|
||||
, WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@@ -304,7 +331,7 @@ public class AutofillService extends AccessibilityService {
|
||||
}
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = FileUtils.openInputStream(items.get(0));
|
||||
is = FileUtils.openInputStream(items.get(lastWhichItem));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@@ -1,57 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="20dp">
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/autofill_radiogroup"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="20dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/use_default"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_default" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_first" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/match"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_match_ellipsis" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/matched"
|
||||
<RadioGroup
|
||||
android:id="@+id/autofill_radiogroup"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:editable="false" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/never"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_never" />
|
||||
<RadioButton
|
||||
android:id="@+id/use_default"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_default" />
|
||||
|
||||
</RadioGroup>
|
||||
<RadioButton
|
||||
android:id="@+id/first"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_first" />
|
||||
|
||||
</LinearLayout>
|
||||
<RadioButton
|
||||
android:id="@+id/match"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_match_ellipsis" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/matched"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
style="?android:attr/buttonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="+"
|
||||
android:id="@+id/matchButton"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/never"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:text="@string/autofill_apps_never"/>
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</LinearLayout>
|
Reference in New Issue
Block a user