aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java31
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java122
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java132
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java3
-rw-r--r--app/src/main/res/layout/autofill_recycler_view.xml11
-rw-r--r--app/src/main/res/layout/autofill_row_layout.xml5
-rw-r--r--app/src/main/res/layout/fragment_autofill.xml15
-rw-r--r--app/src/main/res/menu/autofill_preference.xml12
-rw-r--r--app/src/main/res/xml/preference.xml2
9 files changed, 108 insertions, 225 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 ea4b0a2f..c2a30ffe 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java
@@ -3,7 +3,7 @@ package com.zeapo.pwdstore.autofill;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
-import android.preference.PreferenceManager;
+import android.content.pm.PackageManager;
import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -40,15 +40,20 @@ public class AutofillFragment extends DialogFragment {
String appName = getArguments().getString("appName");
builder.setTitle(appName);
+ try {
+ // since we can't (easily?) pass the drawable as an argument
+ builder.setIcon(callingActivity.getPackageManager().getApplicationIcon(packageName));
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
- // when an app is added for the first time, the radio button selection should reflect
- // the autofill_default setting: hence, defValue
- SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(callingActivity);
- String defValue = settings.getBoolean("autofill_default", true) ? "first" : "never";
SharedPreferences prefs
= getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
- String preference = prefs.getString(packageName, defValue);
+ String preference = prefs.getString(packageName, "");
switch (preference) {
+ case "":
+ ((RadioButton) view.findViewById(R.id.use_default)).toggle();
+ break;
case "first":
((RadioButton) view.findViewById(R.id.first)).toggle();
break;
@@ -77,6 +82,9 @@ public class AutofillFragment extends DialogFragment {
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;
@@ -90,10 +98,10 @@ public class AutofillFragment extends DialogFragment {
}
editor.apply();
int position = getArguments().getInt("position");
- if (position == -1) {
- callingActivity.recyclerAdapter.add(packageName);
- } else {
- callingActivity.recyclerAdapter.notifyItemChanged(position);
+ callingActivity.recyclerAdapter.notifyItemChanged(position);
+
+ if (getArguments().getBoolean("finish")) {
+ callingActivity.finish();
}
}
});
@@ -105,7 +113,8 @@ public class AutofillFragment extends DialogFragment {
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();
}
-
}
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java
index abf1f320..91131956 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java
@@ -1,22 +1,17 @@
package com.zeapo.pwdstore.autofill;
import android.app.DialogFragment;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
+import android.content.Intent;
import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.MatrixCursor;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.SearchView;
-import android.widget.SimpleCursorAdapter;
-import android.widget.TextView;
+import android.support.v7.widget.SearchView;
+import android.view.Menu;
+import android.view.MenuItem;
import com.zeapo.pwdstore.R;
@@ -24,7 +19,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.Map;
public class AutofillPreferenceActivity extends AppCompatActivity {
@@ -43,102 +37,62 @@ public class AutofillPreferenceActivity extends AppCompatActivity {
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
-
- // apps for which the user has custom settings should be in the recycler
+
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List<ResolveInfo> allApps = getPackageManager().queryIntentActivities(intent, 0);
final PackageManager pm = getPackageManager();
- SharedPreferences prefs
- = getSharedPreferences("autofill", Context.MODE_PRIVATE);
- Map<String, ?> prefApps = prefs.getAll();
- ArrayList<ApplicationInfo> apps = new ArrayList<>();
- for (String packageName : prefApps.keySet()) {
- try {
- apps.add(pm.getApplicationInfo(packageName, 0));
- } catch (PackageManager.NameNotFoundException e) {
- // remove invalid entries (from uninstalled apps?)
- SharedPreferences.Editor editor = prefs.edit();
- editor.remove(packageName).apply();
- }
- }
- Collections.sort(apps, new Comparator<ApplicationInfo>() {
+ Collections.sort(allApps, new Comparator<ResolveInfo>() {
@Override
- public int compare(ApplicationInfo lhs, ApplicationInfo rhs) {
+ public int compare(ResolveInfo lhs, ResolveInfo rhs) {
return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString());
}
});
- recyclerAdapter = new AutofillRecyclerAdapter(apps, pm, this);
+ recyclerAdapter = new AutofillRecyclerAdapter(new ArrayList<>(allApps), pm, this);
recyclerView.setAdapter(recyclerAdapter);
- // show the search bar by default but don't open the keyboard
- getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
- final SearchView searchView = (SearchView) findViewById(R.id.app_search);
- searchView.clearFocus();
+ setTitle("Autofill Apps");
- // create search suggestions of apps with icons & names
- final SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() {
- @Override
- public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
- if (view instanceof TextView) {
- ((TextView) view).setText(cursor.getString(columnIndex));
- } else if (view instanceof ImageView) {
- try {
- ((ImageView) view).setImageDrawable(pm.getApplicationIcon(cursor.getString(columnIndex)));
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- return false;
- }
- }
- return true;
- }
- };
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ recyclerView.scrollToPosition(recyclerAdapter.getPosition(extras.getString("packageName")));
+ showDialog(extras.getString("packageName"), extras.getString("appName"));
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.autofill_preference, menu);
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
- final List<ApplicationInfo> allApps = pm.getInstalledApplications(0);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
- public boolean onQueryTextSubmit(String query) {
- return false;
+ public boolean onQueryTextSubmit(String s) {
+ return true;
}
@Override
- public boolean onQueryTextChange(String newText) {
- // should be a better/faster way to do this?
- // TODO do this async probably. it lags.
- MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"});
- for (ApplicationInfo applicationInfo : allApps) {
- if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase())) {
- matrixCursor.addRow(new Object[]{0, applicationInfo.packageName, applicationInfo.loadLabel(pm)});
- }
- }
- SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(AutofillPreferenceActivity.this
- , R.layout.app_list_item, matrixCursor, new String[]{"package", "label"}
- , new int[]{android.R.id.icon1, android.R.id.text1}, 0);
- simpleCursorAdapter.setViewBinder(viewBinder);
- searchView.setSuggestionsAdapter(simpleCursorAdapter);
- return false;
+ public boolean onQueryTextChange(String s) {
+ return true;
}
});
- searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
+ // When using the support library, the setOnActionExpandListener() method is
+ // static and accepts the MenuItem object as an argument
+ MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
@Override
- public boolean onSuggestionSelect(int position) {
- return false;
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ return true;
}
@Override
- public boolean onSuggestionClick(int position) {
- Cursor cursor = searchView.getSuggestionsAdapter().getCursor();
- String packageName = cursor.getString(1);
- String appName = cursor.getString(2);
- showDialog(packageName, appName);
+ public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
});
-
- setTitle("Autofill Apps");
-
- Bundle extras = getIntent().getExtras();
- if (extras != null) {
- showDialog(extras.getString("packageName"), extras.getString("appName"));
- }
+ return super.onCreateOptionsMenu(menu);
}
public void showDialog(String packageName, String appName) {
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java
index 14530879..7c735f18 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java
@@ -2,14 +2,11 @@ package com.zeapo.pwdstore.autofill;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.preference.PreferenceManager;
+import android.content.pm.ResolveInfo;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@@ -18,19 +15,14 @@ import android.widget.TextView;
import com.zeapo.pwdstore.R;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.TreeSet;
public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecyclerAdapter.ViewHolder> {
- private ArrayList<ApplicationInfo> apps;
+ private ArrayList<ResolveInfo> apps;
private PackageManager pm;
private AutofillPreferenceActivity activity;
- private final Set<Integer> selectedItems;
private ActionMode actionMode;
- public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
+ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public View view;
public TextView name;
public TextView secondary;
@@ -44,38 +36,19 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
secondary = (TextView) view.findViewById(R.id.secondary_text);
icon = (ImageView) view.findViewById(R.id.app_icon);
view.setOnClickListener(this);
- view.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
- if (actionMode != null) {
- toggleSelection(getAdapterPosition(), view);
- if (selectedItems.isEmpty()) {
- actionMode.finish();
- }
- } else {
- activity.showDialog(packageName, name.getText().toString());
- }
+ activity.showDialog(packageName, name.getText().toString());
}
- @Override
- public boolean onLongClick(View v) {
- if (actionMode != null) {
- return false;
- }
- toggleSelection(getAdapterPosition(), view);
- // Start the CAB using the ActionMode.Callback
- actionMode = activity.startSupportActionMode(actionModeCallback);
- return true;
- }
}
- public AutofillRecyclerAdapter(ArrayList<ApplicationInfo> apps, PackageManager pm, AutofillPreferenceActivity activity) {
+ public AutofillRecyclerAdapter(ArrayList<ResolveInfo> apps, PackageManager pm, AutofillPreferenceActivity activity) {
this.apps = apps;
this.pm = pm;
this.activity = activity;
- this.selectedItems = new TreeSet<>(Collections.reverseOrder());
}
@Override
@@ -87,30 +60,33 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
@Override
public void onBindViewHolder(AutofillRecyclerAdapter.ViewHolder holder, int position) {
- ApplicationInfo app = apps.get(position);
- holder.name.setText(pm.getApplicationLabel(app));
+ ResolveInfo app = apps.get(position);
+ holder.name.setText(app.loadLabel(pm));
+ holder.icon.setImageDrawable(app.loadIcon(pm));
+ holder.packageName = app.activityInfo.packageName;
+
+ holder.secondary.setVisibility(View.VISIBLE);
+ holder.view.setBackgroundResource(R.color.grey_white_1000);
- // it shouldn't be possible for prefs.getString to not find the app...use defValue anyway
- SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity);
- String defValue = settings.getBoolean("autofill_default", true) ? "first" : "never";
SharedPreferences prefs
= activity.getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
- String preference = prefs.getString(app.packageName, defValue);
+ String preference = prefs.getString(holder.packageName, "");
switch (preference) {
+ case "":
+ holder.secondary.setVisibility(View.GONE);
+ // "android:windowBackground"
+ holder.view.setBackgroundResource(R.color.indigo_50);
+ break;
case "first":
- holder.secondary.setText("Automatically match with password");
+ holder.secondary.setText("Automatically match");
break;
case "never":
- holder.secondary.setText("Never autofill");
+ holder.secondary.setText("Never match");
break;
default:
holder.secondary.setText("Match with " + preference);
break;
}
- holder.icon.setImageDrawable(pm.getApplicationIcon(app));
- holder.packageName = app.packageName;
-
- holder.view.setSelected(selectedItems.contains(position));
}
@Override
@@ -118,79 +94,13 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecycl
return apps.size();
}
- public void add(String packageName) {
- try {
- ApplicationInfo app = pm.getApplicationInfo(packageName, 0);
- this.apps.add(app);
- notifyItemInserted(apps.size());
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- }
-
public int getPosition(String packageName) {
for (int i = 0; i < apps.size(); i++) {
- if (apps.get(i).packageName.equals(packageName)) {
+ if (apps.get(i).activityInfo.packageName.equals(packageName)) {
return i;
}
}
return -1;
}
- private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.getMenuInflater().inflate(R.menu.context_pass, menu);
- return true;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- return false;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_delete_password:
- // don't ask for confirmation
- for (int position : selectedItems) {
- remove(position);
- }
- mode.finish(); // Action picked, so close the CAB
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- for (Iterator it = selectedItems.iterator(); it.hasNext();) {
- // need the setSelected line in onBind
- notifyItemChanged((Integer) it.next());
- it.remove();
- }
- actionMode = null;
- }
- };
-
- public void remove(int position) {
- ApplicationInfo applicationInfo = this.apps.get(position);
- SharedPreferences prefs
- = activity.getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE);
- prefs.edit().remove(applicationInfo.packageName).apply();
-
- this.apps.remove(position);
- this.notifyItemRemoved(position);
- }
-
- public void toggleSelection(int position, View view) {
- if (!selectedItems.remove(position)) {
- selectedItems.add(position);
- view.setSelected(true);
- } else {
- view.setSelected(false);
- }
- }
}
diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java
index bb3b17f2..1b8ff740 100644
--- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java
+++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java
@@ -156,8 +156,9 @@ public class AutofillService extends AccessibilityService {
builder.setNeutralButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
+ // 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.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("packageName", info.getPackageName());
intent.putExtra("appName", appName);
startActivity(intent);
diff --git a/app/src/main/res/layout/autofill_recycler_view.xml b/app/src/main/res/layout/autofill_recycler_view.xml
index 836cbcf5..27afa77d 100644
--- a/app/src/main/res/layout/autofill_recycler_view.xml
+++ b/app/src/main/res/layout/autofill_recycler_view.xml
@@ -2,16 +2,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="true"
- android:focusableInTouchMode="true">
-
- <SearchView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/app_search"
- android:queryHint="Add an app to change its setting"
- android:iconifiedByDefault="false"/>
+ android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/autofill_recycler"
diff --git a/app/src/main/res/layout/autofill_row_layout.xml b/app/src/main/res/layout/autofill_row_layout.xml
index 354f9181..190c651f 100644
--- a/app/src/main/res/layout/autofill_row_layout.xml
+++ b/app/src/main/res/layout/autofill_row_layout.xml
@@ -31,15 +31,14 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="App"
android:id="@+id/app_name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:text="The matched file.gpg/Don't ask"
- android:id="@+id/secondary_text"/>
+ android:id="@+id/secondary_text"
+ android:textColor="@color/grey_600"/>
</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_autofill.xml b/app/src/main/res/layout/fragment_autofill.xml
index 6ad44a0d..e5534f41 100644
--- a/app/src/main/res/layout/fragment_autofill.xml
+++ b/app/src/main/res/layout/fragment_autofill.xml
@@ -13,11 +13,18 @@
android:layout_height="wrap_content"
android:id="@+id/autofill_radiogroup"
>
+ <RadioButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Use default setting"
+ android:id="@+id/use_default"
+ android:layout_gravity="center_vertical"
+ android:checked="false"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Automatically match with password"
+ android:text="Automatically match"
android:id="@+id/first"
android:layout_gravity="center_vertical"
android:checked="false"/>
@@ -29,7 +36,7 @@
android:id="@+id/match"
android:layout_gravity="center_vertical"
android:checked="false"
- android:layout_marginTop="8dp"/>
+ />
<EditText
android:layout_width="match_parent"
@@ -41,11 +48,11 @@
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="Never autofill"
+ android:text="Never match"
android:id="@+id/never"
android:layout_gravity="center_vertical"
android:checked="false"
- android:layout_marginTop="8dp"/>
+ />
</RadioGroup>
diff --git a/app/src/main/res/menu/autofill_preference.xml b/app/src/main/res/menu/autofill_preference.xml
new file mode 100644
index 00000000..77ce95f4
--- /dev/null
+++ b/app/src/main/res/menu/autofill_preference.xml
@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:pwstore="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ tools:context=".pwdstore.autofill.AutofillPreferenceActivity">
+ <item
+ android:id="@+id/action_search"
+ android:icon="@drawable/ic_action_search"
+ android:title="@string/action_search"
+ pwstore:actionViewClass="android.support.v7.widget.SearchView"
+ pwstore:showAsAction="ifRoom|collapseActionView"/>
+
+</menu> \ No newline at end of file
diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml
index 44e38916..e8ba80cc 100644
--- a/app/src/main/res/xml/preference.xml
+++ b/app/src/main/res/xml/preference.xml
@@ -79,7 +79,7 @@
<CheckBoxPreference
android:defaultValue="true"
android:key="autofill_default"
- android:summary="Default to 'Automatically match with password' for apps without custom settings."
+ android:summary="Default to 'Automatically match' for apps without custom settings. Otherwise, 'Never match.'"
android:title="Automatically match by default"/>
</PreferenceCategory>