Merge "Extract the logic of MagnificationMode to the controller" into sc-dev
diff --git a/res/layout/accessibility_edit_magnification_shortcut.xml b/res/layout/accessibility_edit_magnification_shortcut.xml
index 5f885b9..2702e70 100644
--- a/res/layout/accessibility_edit_magnification_shortcut.xml
+++ b/res/layout/accessibility_edit_magnification_shortcut.xml
@@ -47,13 +47,13 @@
android:orientation="vertical">
<Button
- android:id="@+id/switch_shortcut_positive_button"
+ android:id="@+id/custom_positive_button"
style="@style/AccessibilityDialogButton"
android:gravity="center|end"
android:text="@string/accessibility_magnification_switch_shortcut_positive_button"/>
<Button
- android:id="@+id/switch_shortcut_negative_button"
+ android:id="@+id/custom_negative_button"
style="@style/AccessibilityDialogButton"
android:gravity="center|end"
android:text="@string/accessibility_magnification_switch_shortcut_negative_button"/>
diff --git a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
index da3b479..5402a9b 100644
--- a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
+++ b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java
@@ -118,18 +118,19 @@
*
* @param context A valid context
* @param dialogTitle The title of magnify edit shortcut dialog
- * @param listener The listener to determine the action of magnify edit shortcut dialog
+ * @param positiveBtnListener The positive button listener
* @return A magnification edit shortcut dialog in Magnification
*/
- public static Dialog showMagnificationSwitchShortcutDialog(Context context,
- CharSequence dialogTitle, View.OnClickListener listener) {
+ public static Dialog createMagnificationSwitchShortcutDialog(Context context,
+ CharSequence dialogTitle, CustomButtonsClickListener positiveBtnListener) {
+ final View contentView = createSwitchShortcutDialogContentView(context);
final AlertDialog alertDialog = new AlertDialog.Builder(context)
- .setView(createSwitchShortcutDialogContentView(context))
+ .setView(contentView)
.setTitle(dialogTitle)
.create();
- alertDialog.show();
- setEditShortcutButtonsListener(alertDialog, listener);
- setScrollIndicators(alertDialog);
+ setCustomButtonsClickListener(alertDialog, contentView,
+ positiveBtnListener, /* negativeBtnListener= */ null);
+ setScrollIndicators(contentView);
return alertDialog;
}
@@ -169,16 +170,50 @@
View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
}
- private static void setEditShortcutButtonsListener(AlertDialog dialog,
- View.OnClickListener listener) {
- final View contentView = dialog.findViewById(R.id.container_layout);
- final Button positiveButton = contentView.findViewById(
- R.id.switch_shortcut_positive_button);
- final Button negativeButton = contentView.findViewById(
- R.id.switch_shortcut_negative_button);
- positiveButton.setOnClickListener(listener);
- negativeButton.setOnClickListener(v -> dialog.dismiss());
+ interface CustomButtonsClickListener {
+ void onClick(@CustomButton int which);
+ }
+
+ /**
+ * Annotation for customized dialog button type.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ CustomButton.POSITIVE,
+ CustomButton.NEGATIVE,
+ })
+
+ public @interface CustomButton {
+ int POSITIVE = 1;
+ int NEGATIVE = 2;
+ }
+
+ private static void setCustomButtonsClickListener(Dialog dialog, View contentView,
+ CustomButtonsClickListener positiveBtnListener,
+ CustomButtonsClickListener negativeBtnListener) {
+ final Button positiveButton = contentView.findViewById(
+ R.id.custom_positive_button);
+ final Button negativeButton = contentView.findViewById(
+ R.id.custom_negative_button);
+
+ if (positiveButton != null) {
+ positiveButton.setOnClickListener(v -> {
+ if (positiveBtnListener != null) {
+ positiveBtnListener.onClick(CustomButton.POSITIVE);
+ }
+ dialog.dismiss();
+ });
+ }
+
+ if (negativeButton != null) {
+ negativeButton.setOnClickListener(v -> {
+ if (negativeBtnListener != null) {
+ negativeBtnListener.onClick(CustomButton.NEGATIVE);
+ }
+ dialog.dismiss();
+ });
+ }
}
private static View createSwitchShortcutDialogContentView(Context context) {
diff --git a/src/com/android/settings/accessibility/MagnificationCapabilities.java b/src/com/android/settings/accessibility/MagnificationCapabilities.java
index 079b06c..04a2992 100644
--- a/src/com/android/settings/accessibility/MagnificationCapabilities.java
+++ b/src/com/android/settings/accessibility/MagnificationCapabilities.java
@@ -42,12 +42,14 @@
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
+ MagnificationMode.NONE,
MagnificationMode.FULLSCREEN,
MagnificationMode.WINDOW,
MagnificationMode.ALL,
})
public @interface MagnificationMode {
+ int NONE = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
int FULLSCREEN = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
int WINDOW = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
int ALL = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
diff --git a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
index 5dc93b1..67b68cc 100644
--- a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
@@ -16,15 +16,85 @@
package com.android.settings.accessibility;
+import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.settings.accessibility.AccessibilityEditDialogUtils.CustomButton;
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.DialogCreatable;
+import com.android.settings.R;
+import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnCreate;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
-/** Controller that shows the magnification area mode summary. */
-public class MagnificationModePreferenceController extends BasePreferenceController {
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringJoiner;
+
+/** Controller that shows the magnification area mode summary and the preference click behavior. */
+public class MagnificationModePreferenceController extends BasePreferenceController implements
+ DialogCreatable, LifecycleObserver, OnCreate, OnSaveInstanceState {
+
+ private static final int DIALOG_ID_BASE = 10;
+ @VisibleForTesting
+ static final int DIALOG_MAGNIFICATION_MODE = DIALOG_ID_BASE + 1;
+ @VisibleForTesting
+ static final int DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = DIALOG_ID_BASE + 2;
+ @VisibleForTesting
+ static final String EXTRA_MODE = "mode";
+
+ private static final String TAG = "MagnificationModePreferenceController";
+ private static final char COMPONENT_NAME_SEPARATOR = ':';
+
+ private MagnificationSettingsFragment mParentFragment;
+ // The magnification mode in the dialog.
+ private int mMode = MagnificationMode.NONE;
+ private Preference mModePreference;
+
+ @VisibleForTesting
+ ListView mMagnificationModesListView;
+
+ private final List<MagnificationModeInfo> mModeInfos = new ArrayList<>();
public MagnificationModePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
+ initModeInfos();
+ }
+
+ private void initModeInfos() {
+ mModeInfos.add(new MagnificationModeInfo(mContext.getText(
+ R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
+ R.drawable.ic_illustration_fullscreen, MagnificationMode.FULLSCREEN));
+ mModeInfos.add(new MagnificationModeInfo(
+ mContext.getText(R.string.accessibility_magnification_mode_dialog_option_window),
+ null, R.drawable.ic_illustration_window, MagnificationMode.WINDOW));
+ mModeInfos.add(new MagnificationModeInfo(
+ mContext.getText(R.string.accessibility_magnification_mode_dialog_option_switch),
+ mContext.getText(
+ R.string.accessibility_magnification_area_settings_mode_switch_summary),
+ R.drawable.ic_illustration_switch, MagnificationMode.ALL));
}
@Override
@@ -32,10 +102,180 @@
return AVAILABLE;
}
-
@Override
public CharSequence getSummary() {
final int capabilities = MagnificationCapabilities.getCapabilities(mContext);
return MagnificationCapabilities.getSummary(mContext, capabilities);
}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ mMode = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
+ }
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mModePreference = screen.findPreference(getPreferenceKey());
+ mModePreference.setOnPreferenceClickListener(preference -> {
+ mMode = MagnificationCapabilities.getCapabilities(mContext);
+ mParentFragment.showDialog(DIALOG_MAGNIFICATION_MODE);
+ return true;
+ });
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ outState.putInt(EXTRA_MODE, mMode);
+ }
+
+ public void setParentFragment(MagnificationSettingsFragment parentFragment) {
+ mParentFragment = parentFragment;
+ }
+
+ @Override
+ public Dialog onCreateDialog(int dialogId) {
+ switch (dialogId) {
+ case DIALOG_MAGNIFICATION_MODE:
+ return createMagnificationModeDialog();
+
+ case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
+ return createMagnificationShortCutConfirmDialog();
+ }
+ return null;
+ }
+
+ @Override
+ public int getDialogMetricsCategory(int dialogId) {
+ switch (dialogId) {
+ case DIALOG_MAGNIFICATION_MODE:
+ return SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY;
+ case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
+ return SettingsEnums.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT;
+ default:
+ return 0;
+ }
+ }
+
+ private Dialog createMagnificationModeDialog() {
+ mMagnificationModesListView = AccessibilityEditDialogUtils.createSingleChoiceListView(
+ mContext, mModeInfos, this::onMagnificationModeSelected);
+
+ final View headerView = LayoutInflater.from(mContext).inflate(
+ R.layout.accessibility_magnification_mode_header, mMagnificationModesListView,
+ false);
+ mMagnificationModesListView.addHeaderView(headerView, /* data= */ null, /* isSelectable= */
+ false);
+
+ mMagnificationModesListView.setItemChecked(computeSelectionIndex(), true);
+ final CharSequence title = mContext.getString(
+ R.string.accessibility_magnification_mode_dialog_title);
+
+ return AccessibilityEditDialogUtils.createCustomDialog(mContext, title,
+ mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
+ }
+
+ private void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
+ int which) {
+ final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition();
+ if (selectedIndex != AdapterView.INVALID_POSITION) {
+ final MagnificationModeInfo modeInfo =
+ (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
+ selectedIndex);
+ setMode(modeInfo.mMagnificationMode);
+ } else {
+ Log.w(TAG, "invalid index");
+ }
+ }
+
+ private void setMode(int mode) {
+ mMode = mode;
+ MagnificationCapabilities.setCapabilities(mContext, mMode);
+ mModePreference.setSummary(
+ MagnificationCapabilities.getSummary(mContext, mMode));
+ }
+
+ private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position,
+ long id) {
+ final MagnificationModeInfo modeInfo =
+ (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
+ position);
+ if (modeInfo.mMagnificationMode == mMode) {
+ return;
+ }
+ mMode = modeInfo.mMagnificationMode;
+ if (isTripleTapEnabled(mContext) && mMode != MagnificationMode.FULLSCREEN) {
+ mParentFragment.showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+ }
+ }
+
+ private int computeSelectionIndex() {
+ final int modesSize = mModeInfos.size();
+ for (int i = 0; i < modesSize; i++) {
+ if (mModeInfos.get(i).mMagnificationMode == mMode) {
+ return i + mMagnificationModesListView.getHeaderViewsCount();
+ }
+ }
+ Log.w(TAG, "computeSelectionIndex failed");
+ return 0;
+ }
+
+ @VisibleForTesting
+ static boolean isTripleTapEnabled(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
+ }
+
+ private Dialog createMagnificationShortCutConfirmDialog() {
+ final String title = mContext.getString(
+ R.string.accessibility_magnification_switch_shortcut_title);
+ return AccessibilityEditDialogUtils.createMagnificationSwitchShortcutDialog(mContext, title,
+ this::onSwitchShortcutDialogButtonClicked);
+ }
+
+ @VisibleForTesting
+ void onSwitchShortcutDialogButtonClicked(@CustomButton int which) {
+ optOutMagnificationFromTripleTap();
+ //TODO(b/147990389): Merge this function into AccessibilityUtils after the format of
+ // magnification target is changed to ComponentName.
+ optInMagnificationToAccessibilityButton();
+ }
+
+ private void optOutMagnificationFromTripleTap() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
+ }
+
+ private void optInMagnificationToAccessibilityButton() {
+ final String targetKey = Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
+ final String targetString = Settings.Secure.getString(mContext.getContentResolver(),
+ targetKey);
+ if (targetString != null && targetString.contains(MAGNIFICATION_CONTROLLER_NAME)) {
+ return;
+ }
+
+ final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
+
+ if (!TextUtils.isEmpty(targetString)) {
+ joiner.add(targetString);
+ }
+ joiner.add(MAGNIFICATION_CONTROLLER_NAME);
+
+ Settings.Secure.putString(mContext.getContentResolver(), targetKey,
+ joiner.toString());
+ }
+
+ @VisibleForTesting
+ static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo {
+ @MagnificationMode
+ public final int mMagnificationMode;
+
+ MagnificationModeInfo(@NonNull CharSequence title, @Nullable CharSequence summary,
+ @DrawableRes int drawableId, @MagnificationMode int magnificationMode) {
+ super(title, summary, drawableId);
+ mMagnificationMode = magnificationMode;
+ }
+ }
}
diff --git a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
index 520de01..0af40fd 100644
--- a/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationSettingsFragment.java
@@ -16,88 +16,22 @@
package com.android.settings.accessibility;
-import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
-import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
-import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
-
import android.app.Dialog;
import android.app.settings.SettingsEnums;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ListView;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
+import android.content.Context;
import com.android.settings.R;
-import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
/** Settings page for magnification. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MagnificationSettingsFragment extends DashboardFragment {
private static final String TAG = "MagnificationSettingsFragment";
- private static final String PREF_KEY_MODE = "magnification_mode";
- @VisibleForTesting
- static final int DIALOG_MAGNIFICATION_CAPABILITY = 1;
- @VisibleForTesting
- static final int DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = 2;
- @VisibleForTesting
- static final String EXTRA_CAPABILITY = "capability";
- private static final int NONE = 0;
- private static final char COMPONENT_NAME_SEPARATOR = ':';
-
- private Preference mModePreference;
- @VisibleForTesting
- Dialog mDialog;
-
- @VisibleForTesting
- ListView mMagnificationModesListView;
- private int mCapabilities = NONE;
-
- private final List<MagnificationModeInfo> mModeInfos = new ArrayList<>();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (savedInstanceState != null) {
- mCapabilities = savedInstanceState.getInt(EXTRA_CAPABILITY, NONE);
- }
- if (mCapabilities == NONE) {
- mCapabilities = MagnificationCapabilities.getCapabilities(getPrefContext());
- }
- initModeInfos();
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- initModePreference();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- outState.putInt(EXTRA_CAPABILITY, mCapabilities);
- super.onSaveInstanceState(outState);
- }
+ private MagnificationModePreferenceController mMagnificationModePreferenceController;
@Override
public int getMetricsCategory() {
@@ -105,15 +39,23 @@
}
@Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mMagnificationModePreferenceController = use(MagnificationModePreferenceController.class);
+ mMagnificationModePreferenceController.setParentFragment(this);
+ }
+
+ @Override
+ protected void showDialog(int dialogId) {
+ super.showDialog(dialogId);
+ }
+
+ @Override
public int getDialogMetricsCategory(int dialogId) {
- switch (dialogId) {
- case DIALOG_MAGNIFICATION_CAPABILITY:
- return SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY;
- case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
- return SettingsEnums.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT;
- default:
- return 0;
+ if (mMagnificationModePreferenceController != null) {
+ return mMagnificationModePreferenceController.getDialogMetricsCategory(dialogId);
}
+ return 0;
}
@Override
@@ -128,155 +70,13 @@
@Override
public Dialog onCreateDialog(int dialogId) {
- final CharSequence title;
-
- switch (dialogId) {
- case DIALOG_MAGNIFICATION_CAPABILITY:
- mDialog = createMagnificationModeDialog();
- return mDialog;
- case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
- title = getPrefContext().getString(
- R.string.accessibility_magnification_switch_shortcut_title);
- mDialog = AccessibilityEditDialogUtils.showMagnificationSwitchShortcutDialog(
- getPrefContext(), title, this::onSwitchShortcutDialogPositiveButtonClicked);
- return mDialog;
- }
- throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
- }
-
- private Dialog createMagnificationModeDialog() {
- mMagnificationModesListView = AccessibilityEditDialogUtils.createSingleChoiceListView(
- getPrefContext(), mModeInfos, this::onMagnificationModeSelected);
-
- final View headerView = LayoutInflater.from(getPrefContext()).inflate(
- R.layout.accessibility_magnification_mode_header, mMagnificationModesListView,
- false);
- mMagnificationModesListView.addHeaderView(headerView, null, /* isSelectable= */false);
-
- mMagnificationModesListView.setItemChecked(computeSelectedMagnificationModeIndex(), true);
- final CharSequence title = getPrefContext().getString(
- R.string.accessibility_magnification_mode_dialog_title);
-
- return AccessibilityEditDialogUtils.createCustomDialog(getPrefContext(), title,
- mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
- }
-
- private int computeSelectedMagnificationModeIndex() {
- final int size = mModeInfos.size();
- for (int i = 0; i < size; i++) {
- if (mModeInfos.get(i).mMagnificationMode == mCapabilities) {
- return i + mMagnificationModesListView.getHeaderViewsCount();
+ if (mMagnificationModePreferenceController != null) {
+ final Dialog dialog = mMagnificationModePreferenceController.onCreateDialog(dialogId);
+ if (dialog != null) {
+ return dialog;
}
}
- Log.w(TAG, "chosen mode" + mCapabilities + "is not in the list");
- return 0;
- }
-
- private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position,
- long id) {
- final MagnificationModeInfo modeInfo =
- (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(position);
- if (modeInfo.mMagnificationMode == mCapabilities) {
- return;
- }
- mCapabilities = modeInfo.mMagnificationMode;
- if (isTripleTapEnabled() && mCapabilities != MagnificationMode.FULLSCREEN) {
- showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
- }
- }
-
- private void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
- int which) {
- final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition();
- if (selectedIndex != AdapterView.INVALID_POSITION) {
- final MagnificationModeInfo modeInfo =
- (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
- selectedIndex);
- updateCapabilities(modeInfo.mMagnificationMode);
- } else {
- Log.w(TAG, "no checked item in the list");
- }
- }
-
- private void updateCapabilities(int mode) {
- mCapabilities = mode;
- MagnificationCapabilities.setCapabilities(getPrefContext(), mCapabilities);
- mModePreference.setSummary(
- MagnificationCapabilities.getSummary(getPrefContext(), mCapabilities));
- }
-
- private void initModeInfos() {
- mModeInfos.clear();
- mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
- R.string.accessibility_magnification_mode_dialog_option_full_screen), null,
- R.drawable.ic_illustration_fullscreen, MagnificationMode.FULLSCREEN));
- mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
- R.string.accessibility_magnification_mode_dialog_option_window), null,
- R.drawable.ic_illustration_window, MagnificationMode.WINDOW));
- mModeInfos.add(new MagnificationModeInfo(getPrefContext().getText(
- R.string.accessibility_magnification_mode_dialog_option_switch),
- getPrefContext().getText(
- R.string.accessibility_magnification_area_settings_mode_switch_summary),
- R.drawable.ic_illustration_switch, MagnificationMode.ALL));
- }
-
- @VisibleForTesting
- static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo {
- @MagnificationMode
- public final int mMagnificationMode;
-
- MagnificationModeInfo(@NonNull CharSequence title, @Nullable CharSequence summary,
- @DrawableRes int drawableId, @MagnificationMode int magnificationMode) {
- super(title, summary, drawableId);
- mMagnificationMode = magnificationMode;
- }
- }
-
- private void initModePreference() {
- mModePreference = findPreference(PREF_KEY_MODE);
- mModePreference.setOnPreferenceClickListener(preference -> {
- mCapabilities = MagnificationCapabilities.getCapabilities(getPrefContext());
- showDialog(DIALOG_MAGNIFICATION_CAPABILITY);
- return true;
- });
- }
-
- private void onSwitchShortcutDialogPositiveButtonClicked(View view) {
- //TODO(b/147990389): Merge this function into util until magnification change format to
- // Component.
- optOutMagnificationFromTripleTap();
- optInMagnificationToAccessibilityButton();
-
- mDialog.dismiss();
- }
-
- private void optOutMagnificationFromTripleTap() {
- Settings.Secure.putInt(getPrefContext().getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
- }
-
- private void optInMagnificationToAccessibilityButton() {
- final String targetKey = Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
- final String targetString = Settings.Secure.getString(getPrefContext().getContentResolver(),
- targetKey);
- if (targetString.contains(MAGNIFICATION_CONTROLLER_NAME)) {
- return;
- }
-
- final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
-
- if (!TextUtils.isEmpty(targetString)) {
- joiner.add(targetString);
- }
- joiner.add(MAGNIFICATION_CONTROLLER_NAME);
-
- Settings.Secure.putString(getPrefContext().getContentResolver(), targetKey,
- joiner.toString());
- }
-
- private boolean isTripleTapEnabled() {
- return Settings.Secure.getInt(getPrefContext().getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
+ throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
index ac7f073..b0d0356 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationCapabilitiesTest.java
@@ -56,4 +56,11 @@
R.string.accessibility_magnification_area_settings_full_screen_summary);
assertThat(actualString).isEqualTo(expectedString);
}
+
+ @Test
+ public void getCapabilities_unset_defaultValue() {
+ final int windowCapabilities = MagnificationCapabilities.getCapabilities(mContext);
+ assertThat(windowCapabilities).isEqualTo(
+ MagnificationCapabilities.MagnificationMode.FULLSCREEN);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
index 7461235..4b053ab 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
@@ -16,40 +16,143 @@
package com.android.settings.accessibility;
+import static androidx.lifecycle.Lifecycle.Event.ON_CREATE;
+
+import static com.android.settings.accessibility.AccessibilityEditDialogUtils.CustomButton;
+import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
+import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
+import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
+import android.os.Bundle;
import android.provider.Settings;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import androidx.fragment.app.FragmentManager;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowDashboardFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowDashboardFragment.class)
public class MagnificationModePreferenceControllerTest {
private static final String PREF_KEY = "screen_magnification_mode";
- private static final String KEY_CAPABILITY =
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY;
- private static final int WINDOW_SCREEN_VALUE = 2;
- private static final int ALL_VALUE = 3;
+ private static final int MAGNIFICATION_MODE_DEFAULT = MagnificationMode.ALL;
+ @Rule
+ public MockitoRule mocks = MockitoJUnit.rule();
+
+ @Mock
+ private PreferenceScreen mScreen;
private Context mContext;
+ private TestMagnificationSettingsFragment mFragment;
private MagnificationModePreferenceController mController;
+ private Preference mModePreference;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new MagnificationModePreferenceController(mContext, PREF_KEY);
+ mScreen = spy(new PreferenceScreen(mContext, null));
+ mModePreference = new Preference(mContext);
+ mFragment = spy(new TestMagnificationSettingsFragment(mController));
+
+ doReturn(mScreen).when(mFragment).getPreferenceScreen();
+ doReturn(mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)).when(
+ mFragment).getChildFragmentManager();
+ mContext.setTheme(R.style.Theme_AppCompat);
+ doReturn(mModePreference).when(mScreen).findPreference(PREF_KEY);
+ MagnificationCapabilities.setCapabilities(mContext, MAGNIFICATION_MODE_DEFAULT);
+ showPreferenceOnTheScreen(null);
+ mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
+ }
+
+ @Test
+ public void settingsModeIsDefault_checkedModeInDialogIsDefault() {
+ assertThat(getCheckedModeFromDialog()).isEqualTo(
+ MAGNIFICATION_MODE_DEFAULT);
+ }
+
+ @Test
+ public void choseModeIsDifferentFromInSettings_checkedModeInDialogIsExpected() {
+ performItemClickWith(MagnificationMode.WINDOW);
+
+ assertThat(getCheckedModeFromDialog()).isEqualTo(MagnificationMode.WINDOW);
+ }
+
+ @Test
+ public void dialogIsReCreated_settingsModeIsAllAndChoseWindowMode_checkedModeIsWindow() {
+ showPreferenceOnTheScreen(null);
+ performItemClickWith(MagnificationMode.WINDOW);
+
+ reshowPreferenceOnTheScreen();
+ mFragment.showDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
+
+ assertThat(getCheckedModeFromDialog()).isEqualTo(
+ MagnificationMode.WINDOW);
+ }
+
+ @Test
+ public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
+ enableTripleTap();
+
+ performItemClickWith(MagnificationMode.WINDOW);
+
+ verify(mFragment).showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+ }
+
+ @Test
+ public void chooseModeAll_modeAllInSettingsAndTripleTapEnabled_notShowShortcutDialog() {
+ enableTripleTap();
+ MagnificationCapabilities.setCapabilities(mContext,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
+ mFragment.onCreate(Bundle.EMPTY);
+ mFragment.onCreateDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
+
+ performItemClickWith(MagnificationMode.ALL);
+
+ verify(mFragment, never()).showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+ }
+
+ @Test
+ public void onSwitchShortcutDialogPositiveButtonClicked_TripleTapEnabled_TripleTapDisabled() {
+ enableTripleTap();
+
+ mController.onSwitchShortcutDialogButtonClicked(CustomButton.POSITIVE);
+
+ assertThat(MagnificationModePreferenceController.isTripleTapEnabled(mContext)).isFalse();
}
@Test
public void getSummary_saveWindowScreen_shouldReturnWindowScreenSummary() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- KEY_CAPABILITY, WINDOW_SCREEN_VALUE);
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
assertThat(mController.getSummary())
.isEqualTo(mContext.getString(
@@ -58,11 +161,93 @@
@Test
public void getSummary_saveAll_shouldReturnAllSummary() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- KEY_CAPABILITY, ALL_VALUE);
+ MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
assertThat(mController.getSummary())
.isEqualTo(mContext.getString(
R.string.accessibility_magnification_area_settings_all_summary));
}
+
+ private int getCheckedModeFromDialog() {
+ final ListView listView = mController.mMagnificationModesListView;
+ assertThat(listView).isNotNull();
+
+ final int checkedPosition = listView.getCheckedItemPosition();
+ final MagnificationModeInfo modeInfo =
+ (MagnificationModeInfo) listView.getAdapter().getItem(checkedPosition);
+ return modeInfo.mMagnificationMode;
+ }
+
+ private void performItemClickWith(@MagnificationMode int mode) {
+ final ListView listView = mController.mMagnificationModesListView;
+ assertThat(listView).isNotNull();
+
+ int modeIndex = AdapterView.NO_ID;
+ // Index 0 is header.
+ for (int i = 1; i < listView.getAdapter().getCount(); i++) {
+ final MagnificationModeInfo modeInfo =
+ (MagnificationModeInfo) listView.getAdapter().getItem(i);
+ if (modeInfo.mMagnificationMode == mode) {
+ modeIndex = i;
+ break;
+ }
+ }
+ if (modeIndex == AdapterView.NO_ID) {
+ throw new RuntimeException("The mode is not in the list.");
+ }
+
+ listView.performItemClick(listView.getChildAt(modeIndex), modeIndex, modeIndex);
+ }
+
+ private void enableTripleTap() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
+ }
+
+ private void reshowPreferenceOnTheScreen() {
+ final Bundle bundle = new Bundle();
+ mFragment.onSaveInstanceState(bundle);
+ mFragment.onDetach();
+ showPreferenceOnTheScreen(bundle);
+
+ }
+
+ private void showPreferenceOnTheScreen(Bundle savedInstanceState) {
+ mFragment.onAttach(mContext);
+ mFragment.onCreate(savedInstanceState);
+ mController.displayPreference(mScreen);
+ }
+
+ private static class TestMagnificationSettingsFragment extends MagnificationSettingsFragment {
+
+ TestMagnificationSettingsFragment(AbstractPreferenceController... controllers) {
+ // Add given controllers for injection. Although controllers will be added in
+ // onAttach(). use(AbstractPreferenceController.class) returns the first added one.
+ for (int i = 0; i < controllers.length; i++) {
+ addPreferenceController(controllers[i]);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // Simulate the observable behaviour because ShadowDashFragment doesn't call
+ // super.create.
+
+ getSettingsLifecycle().onCreate(icicle);
+ getSettingsLifecycle().handleLifecycleEvent(ON_CREATE);
+ }
+
+ @Override
+ protected void showDialog(int dialogId) {
+ super.showDialog(dialogId);
+ // In current fragment architecture, we could assume onCreateDialog is called directly.
+ onCreateDialog(dialogId);
+ }
+
+ @Override
+ protected void addPreferenceController(AbstractPreferenceController controller) {
+ super.addPreferenceController(controller);
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
index 11128e4..789362b 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationSettingsFragmentTest.java
@@ -16,201 +16,34 @@
package com.android.settings.accessibility;
-import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
-import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
-import static com.android.settings.accessibility.MagnificationSettingsFragment.MagnificationModeInfo;
-
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import android.content.Context;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import androidx.fragment.app.FragmentManager;
-import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
-import com.android.settings.testutils.shadow.ShadowDashboardFragment;
+import com.android.settings.testutils.XmlTestUtils;
-import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
+
+import java.util.List;
/** Tests for {@link MagnificationSettingsFragment} */
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowDashboardFragment.class)
public class MagnificationSettingsFragmentTest {
-
- @Rule
- public MockitoRule mocks = MockitoJUnit.rule();
-
- @Mock
- private PreferenceManager mPreferenceManager;
-
- private static final String EXTRA_CAPABILITY =
- MagnificationSettingsFragment.EXTRA_CAPABILITY;
-
private final Context mContext = ApplicationProvider.getApplicationContext();
- private TestMagnificationSettingsFragment mFragment;
-
- @Before
- public void setUpFragment() {
- mFragment = spy(new TestMagnificationSettingsFragment());
- when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
- when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
- doReturn(mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)).when(
- mFragment).getChildFragmentManager();
- mContext.setTheme(R.style.Theme_AppCompat);
- }
@Test
- public void onCreateDialog_capabilitiesInBundle_checkedModeInDialogIsExpected() {
- final Bundle windowModeSavedInstanceState = new Bundle();
- windowModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-
- mFragment.onCreate(windowModeSavedInstanceState);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.WINDOW);
- }
-
- @Test
- public void onCreateDialog_capabilitiesInSetting_checkedModeInDialogIsExpected() {
- MagnificationCapabilities.setCapabilities(mContext,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- mFragment.onCreate(Bundle.EMPTY);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.FULLSCREEN);
- }
-
- @Test
- public void onCreateDialog_choseModeIsDifferentFromInSettings_ShowUsersChoseModeInDialog() {
- final Bundle allModeSavedInstanceState = new Bundle();
- allModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
-
- MagnificationCapabilities.setCapabilities(mContext,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
- mFragment.onCreate(allModeSavedInstanceState);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.ALL);
- }
-
- @Test
- public void onCreateDialog_emptySettingsAndBundle_checkedModeInDialogIsDefaultValue() {
- mFragment.onCreate(Bundle.EMPTY);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- assertThat(getChoseModeFromDialog()).isEqualTo(MagnificationMode.FULLSCREEN);
- }
-
- @Test
- public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
- enableTripleTap();
- final Bundle fullScreenModeSavedInstanceState = new Bundle();
- fullScreenModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- mFragment.onCreate(fullScreenModeSavedInstanceState);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- performItemClickWith(MagnificationMode.WINDOW);
-
- verify(mFragment).showDialog(
- MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
- }
-
- @Test
- public void chooseModeAll_tripleTapEnabled_showSwitchShortcutDialog() {
- enableTripleTap();
- final Bundle fullScreenModeSavedInstanceState = new Bundle();
- fullScreenModeSavedInstanceState.putInt(EXTRA_CAPABILITY,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
- mFragment.onCreate(fullScreenModeSavedInstanceState);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- performItemClickWith(MagnificationMode.ALL);
-
- verify(mFragment).showDialog(
- MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
- }
-
- @Test
- public void chooseWindowMode_WindowModeInSettingsAndTripleTapEnabled_notShowShortCutDialog() {
- enableTripleTap();
- MagnificationCapabilities.setCapabilities(mContext,
- Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
- mFragment.onCreate(Bundle.EMPTY);
- mFragment.onCreateDialog(MagnificationSettingsFragment.DIALOG_MAGNIFICATION_CAPABILITY);
-
- performItemClickWith(MagnificationMode.WINDOW);
-
- verify(mFragment, never()).showDialog(
- MagnificationSettingsFragment.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
- }
-
- private int getChoseModeFromDialog() {
- final ListView listView = mFragment.mMagnificationModesListView;
- assertThat(listView).isNotNull();
-
- final int checkedPosition = listView.getCheckedItemPosition();
- final MagnificationModeInfo modeInfo =
- (MagnificationModeInfo) listView.getAdapter().getItem(
- checkedPosition);
- return modeInfo.mMagnificationMode;
- }
-
- private void performItemClickWith(@MagnificationMode int mode) {
- final ListView listView = mFragment.mMagnificationModesListView;
- assertThat(listView).isNotNull();
-
- int modeIndex = AdapterView.NO_ID;
- // Index 0 is header.
- for (int i = 1; i < listView.getAdapter().getCount(); i++) {
- final MagnificationModeInfo modeInfo =
- (MagnificationModeInfo) listView.getAdapter().getItem(i);
- if (modeInfo.mMagnificationMode == mode) {
- modeIndex = i;
- break;
- }
- }
- if (modeIndex == AdapterView.NO_ID) {
- throw new RuntimeException("The mode is not in the list.");
- }
-
- listView.performItemClick(listView.getChildAt(modeIndex), modeIndex, modeIndex);
- }
-
- private void enableTripleTap() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON);
- }
-
- public static class TestMagnificationSettingsFragment extends MagnificationSettingsFragment {
- public TestMagnificationSettingsFragment() {}
-
- @Override
- protected void showDialog(int dialogId) {
- super.showDialog(dialogId);
- }
+ public void getNonIndexableKeys_existInXmlLayout() {
+ final List<String> niks =
+ ShortcutsSettingsFragment.SEARCH_INDEX_DATA_PROVIDER
+ .getNonIndexableKeys(mContext);
+ final List<String> keys =
+ XmlTestUtils.getKeysFromPreferenceXml(mContext,
+ R.xml.accessibility_magnification_service_settings);
+ assertThat(keys).containsAtLeastElementsIn(niks);
}
}