aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
diff options
context:
space:
mode:
authorwongma7 <wongma7@users.noreply.github.com>2016-01-05 19:40:44 -0500
committerwongma7 <wongma7@users.noreply.github.com>2016-01-05 19:40:44 -0500
commit2064c2eaac88216e6cfb6819831c3afe39158047 (patch)
tree031d0cb46a2e473bef302642c56cdd684a460cfe /app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
parent9e930ae92351c4044e3efb1c715c99c87fc7edd7 (diff)
parent5cf345eaa3e37cfaca82aa8f7d66328361ca27c3 (diff)
downloadHardenedPass-2064c2eaac88216e6cfb6819831c3afe39158047.tar.gz
HardenedPass-2064c2eaac88216e6cfb6819831c3afe39158047.zip
Merge pull request #146 from zeapo/webview
Autofill: multiple associations per app & WebView/Chrome
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java')
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java200
1 files changed, 165 insertions, 35 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
index 5d342f4a..583b5064 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
@@ -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,23 @@ import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
import android.widget.EditText;
+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;
+ private ArrayAdapter<String> adapter;
+ private boolean isWeb;
public AutofillFragment() {
}
@@ -32,23 +41,60 @@ public class AutofillFragment extends DialogFragment {
// need to interact with the recyclerAdapter which is a member of activity
final AutofillPreferenceActivity callingActivity = (AutofillPreferenceActivity) getActivity();
LayoutInflater inflater = callingActivity.getLayoutInflater();
+
final View view = inflater.inflate(R.layout.fragment_autofill, null);
builder.setView(view);
final String packageName = getArguments().getString("packageName");
- String appName = getArguments().getString("appName");
+ final String appName = getArguments().getString("appName");
+ isWeb = getArguments().getBoolean("isWeb");
- builder.setTitle(appName);
+ // set the dialog icon and title or webURL editText
+ String iconPackageName;
+ if (!isWeb) {
+ iconPackageName = packageName;
+ builder.setTitle(appName);
+ view.findViewById(R.id.webURL).setVisibility(View.GONE);
+ } else {
+ iconPackageName = "com.android.browser";
+ builder.setTitle("Website");
+ ((EditText) view.findViewById(R.id.webURL)).setText(packageName);
+ }
try {
- // since we can't (easily?) pass the drawable as an argument
- builder.setIcon(callingActivity.getPackageManager().getApplicationIcon(packageName));
+ builder.setIcon(callingActivity.getPackageManager().getApplicationIcon(iconPackageName));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
- SharedPreferences prefs
- = getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
+ // 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));
+ }
+ });
+
+ // set the existing preference, if any
+ SharedPreferences prefs;
+ if (!isWeb) {
+ prefs = getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
+ } else {
+ prefs = getActivity().getApplicationContext().getSharedPreferences("autofill_web", Context.MODE_PRIVATE);
+ }
String preference = prefs.getString(packageName, "");
switch (preference) {
case "":
@@ -62,9 +108,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,48 +122,130 @@ 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();
+ // write to preferences when OK clicked
builder.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.autofill_radiogroup);
- switch (radioGroup.getCheckedRadioButtonId()) {
- case R.id.use_default:
- editor.remove(packageName);
- break;
- case R.id.first:
- editor.putString(packageName, "/first");
- break;
- case R.id.never:
- editor.putString(packageName, "/never");
- break;
- default:
- EditText matched = (EditText) view.findViewById(R.id.matched);
- String path = matched.getText().toString();
- editor.putString(packageName, path);
- }
- editor.apply();
- // if recyclerAdapter has not loaded yet, there is no need to notifyItemChanged
- if (callingActivity.recyclerAdapter != null) {
- int position = callingActivity.recyclerAdapter.getPosition(packageName);
- callingActivity.recyclerAdapter.notifyItemChanged(position);
- }
}
});
builder.setNegativeButton(R.string.dialog_cancel, null);
+ final SharedPreferences.Editor editor = prefs.edit();
+ if (isWeb) {
+ builder.setNeutralButton(R.string.autofill_apps_delete, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (callingActivity.recyclerAdapter != null
+ && packageName != null && !packageName.equals("")) {
+ editor.remove(packageName);
+ callingActivity.recyclerAdapter.removeWebsite(packageName);
+ editor.apply();
+ }
+ }
+ });
+ }
return builder.create();
}
+ // need to the onClick here for buttons to dismiss dialog only when wanted
+ @Override
+ public void onStart() {
+ super.onStart();
+ AlertDialog ad = (AlertDialog) getDialog();
+ if(ad != null) {
+ Button positiveButton = ad.getButton(Dialog.BUTTON_POSITIVE);
+ positiveButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AutofillPreferenceActivity callingActivity = (AutofillPreferenceActivity) getActivity();
+ Dialog dialog = getDialog();
+
+ SharedPreferences prefs;
+ if (!isWeb) {
+ prefs = getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
+ } else {
+ prefs = getActivity().getApplicationContext().getSharedPreferences("autofill_web", Context.MODE_PRIVATE);
+ }
+ SharedPreferences.Editor editor = prefs.edit();
+
+ String packageName = getArguments().getString("packageName", "");
+ if (isWeb) {
+ packageName = ((EditText) dialog.findViewById(R.id.webURL)).getText().toString();
+
+ // handle some errors and don't dismiss the dialog
+ EditText webURL = (EditText) dialog.findViewById(R.id.webURL);
+ if (packageName.equals("")) {
+ webURL.setError("URL cannot be blank");
+ return;
+ }
+ String oldPackageName = getArguments().getString("packageName", "");
+ if (!oldPackageName.equals(packageName) && prefs.getAll().containsKey(packageName)) {
+ webURL.setError("URL already exists");
+ return;
+ }
+ }
+
+ // write to preferences accordingly
+ RadioGroup radioGroup = (RadioGroup) dialog.findViewById(R.id.autofill_radiogroup);
+ switch (radioGroup.getCheckedRadioButtonId()) {
+ case R.id.use_default:
+ if (!isWeb) {
+ editor.remove(packageName);
+ } else {
+ editor.putString(packageName, "");
+ }
+ break;
+ case R.id.first:
+ editor.putString(packageName, "/first");
+ break;
+ case R.id.never:
+ editor.putString(packageName, "/never");
+ break;
+ default:
+ 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();
+
+ // notify the recycler adapter if it is loaded
+ if (callingActivity.recyclerAdapter != null) {
+ int position;
+ if (!isWeb) {
+ String appName = getArguments().getString("appName", "");
+ position = callingActivity.recyclerAdapter.getPosition(appName);
+ callingActivity.recyclerAdapter.notifyItemChanged(position);
+ } else {
+ position = callingActivity.recyclerAdapter.getPosition(packageName);
+ String oldPackageName = getArguments().getString("packageName", "");
+ if (oldPackageName.equals(packageName)) {
+ callingActivity.recyclerAdapter.notifyItemChanged(position);
+ } else if (oldPackageName.equals("")){
+ callingActivity.recyclerAdapter.addWebsite(packageName);
+ } else {
+ editor.remove(oldPackageName);
+ callingActivity.recyclerAdapter.updateWebsite(oldPackageName, packageName);
+ }
+ }
+ }
+
+ dismiss();
+ }
+ });
+ }
+ }
+
@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"));
}
}
}