Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33f3e3f4 authored by Matthew Fritze's avatar Matthew Fritze
Browse files

Search results always highlight proper results

In fragments where preferences were being injected after
the super#onResume, the incorrect preference was
being highlighted as the selected result.

This is because the index of the preference is calculated
in SettingsPreferenceFragment#onResume, but the index is
not checked again before the item is highlighted.

Instead, we calculate index right before we highlight.

Change-Id: Idaa655f682a1a6186c1996fb51d352589bbeda0f
Fixes: 62179739
Test: runtest --path packages/apps/Settings/tests/app/src/com/android/settings/SettingsPreferenceFragmentTest.java
parent f702e391
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -68,7 +68,8 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

    private static final String TAG = "SettingsPreference";

    private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
    @VisibleForTesting
    static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;

    private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";

@@ -86,7 +87,6 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
    private ContentResolver mContentResolver;

    private String mPreferenceKey;
    private boolean mPreferenceHighlighted = false;

    private RecyclerView.Adapter mCurrentRootAdapter;
    private boolean mIsDataSetObserverRegistered = false;
@@ -130,10 +130,14 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

    private View mEmptyView;
    private LinearLayoutManager mLayoutManager;
    private HighlightablePreferenceGroupAdapter mAdapter;
    private ArrayMap<String, Preference> mPreferenceCache;
    private boolean mAnimationAllowed;

    @VisibleForTesting
    public HighlightablePreferenceGroupAdapter mAdapter;
    @VisibleForTesting
    public boolean mPreferenceHighlighted = false;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
@@ -268,8 +272,13 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

    public void highlightPreferenceIfNeeded() {
        if (isAdded() && !mPreferenceHighlighted &&!TextUtils.isEmpty(mPreferenceKey)) {
            getView().postDelayed(new Runnable() {
                @Override
                public void run() {
                    highlightPreference(mPreferenceKey);
                }
            }, DELAY_HIGHLIGHT_DURATION_MILLIS);
        }
    }

    protected void onDataSetChanged() {
@@ -399,18 +408,14 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

    private void highlightPreference(String key) {
        final int position = canUseListViewForHighLighting(key);
        if (position >= 0) {
        if (position < 0) {
            return;
        }

        mPreferenceHighlighted = true;
        mLayoutManager.scrollToPosition(position);

            getView().postDelayed(new Runnable() {
                @Override
                public void run() {
        mAdapter.highlight(position);
    }
            }, DELAY_HIGHLIGHT_DURATION_MILLIS);
        }
    }

    private int findListPositionFromKey(PreferenceGroupAdapter adapter, String key) {
        final int count = adapter.getItemCount();
@@ -765,6 +770,9 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

    public static class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {

        @VisibleForTesting(otherwise=VisibleForTesting.NONE)
        int initialHighlightedPosition = -1;

        private int mHighlightPosition = -1;

        public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
@@ -773,6 +781,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF

        public void highlight(int position) {
            mHighlightPosition = position;
            initialHighlightedPosition = position;
            notifyDataSetChanged();
        }

+73 −0
Original line number Diff line number Diff line
package com.android.settings;

import android.content.Intent;
import android.content.Context;

import android.app.Instrumentation;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroupAdapter;
import com.android.settings.accessibility.AccessibilitySettings;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static com.google.common.truth.Truth.assertThat;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class SettingsPreferenceFragmentTest {

    private Instrumentation mInstrumentation;
    private Context mTargetContext;

    @Before
    public void setUp() throws Exception {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mTargetContext = mInstrumentation.getTargetContext();
    }

    @Test
    public void testHighlightCaptions() throws InterruptedException {
        final String prefKey = "captioning_preference_screen";
        Bundle args = new Bundle();
        args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, prefKey);

        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setClass(mTargetContext, SubSettings.class);
        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT,
                "com.android.settings.accessibility.AccessibilitySettings");
        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);

        SettingsActivity activity  = (SettingsActivity) mInstrumentation.startActivitySync(intent);
        AccessibilitySettings fragment = (AccessibilitySettings)
                activity.getFragmentManager().getFragments().get(0);

        // Allow time for highlight from post-delay.
        Thread.sleep(SettingsPreferenceFragment.DELAY_HIGHLIGHT_DURATION_MILLIS);
        if (!fragment.mPreferenceHighlighted) {
            Thread.sleep(SettingsPreferenceFragment.DELAY_HIGHLIGHT_DURATION_MILLIS);
        }

        int prefPosition = -1;
        PreferenceGroupAdapter adapter = (PreferenceGroupAdapter)
                fragment.getListView().getAdapter();
        for (int n = 0, count = adapter.getItemCount(); n < count; n++) {
            final Preference preference = adapter.getItem(n);
            final String preferenceKey = preference.getKey();
            if (preferenceKey.equals(prefKey)) {
                prefPosition = n;
                break;
            }
        }

        assertThat(fragment.mAdapter.initialHighlightedPosition).isEqualTo(prefPosition);
    }
}