diff --git a/src/com/android/settings/search2/InlineSwitchViewHolder.java b/src/com/android/settings/search2/InlineSwitchViewHolder.java index 54d352353ac..ad99af8fc00 100644 --- a/src/com/android/settings/search2/InlineSwitchViewHolder.java +++ b/src/com/android/settings/search2/InlineSwitchViewHolder.java @@ -17,14 +17,11 @@ package com.android.settings.search2; -import android.app.Fragment; -import android.util.Log; +import android.content.Context; import android.view.View; -import android.view.ViewParent; import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; -import android.content.Context; import com.android.internal.widget.PreferenceImageView; import com.android.settings.R; @@ -52,7 +49,7 @@ public class InlineSwitchViewHolder extends SearchViewHolder { } @Override - public void onBind(Fragment fragment, SearchResult result) { + public void onBind(SearchFragment fragment, SearchResult result) { if (mContext == null) { return; } @@ -62,6 +59,7 @@ public class InlineSwitchViewHolder extends SearchViewHolder { switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + fragment.onSearchResultClicked(); payload.setSwitchValue(mContext, isChecked); } }); diff --git a/src/com/android/settings/search2/IntentSearchViewHolder.java b/src/com/android/settings/search2/IntentSearchViewHolder.java index da3f7240d8a..c9952fa6bda 100644 --- a/src/com/android/settings/search2/IntentSearchViewHolder.java +++ b/src/com/android/settings/search2/IntentSearchViewHolder.java @@ -15,7 +15,6 @@ */ package com.android.settings.search2; -import android.app.Fragment; import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -40,7 +39,7 @@ public class IntentSearchViewHolder extends SearchViewHolder { } @Override - public void onBind(final Fragment fragment, final SearchResult result) { + public void onBind(final SearchFragment fragment, final SearchResult result) { titleView.setText(result.title); summaryView.setText(result.summary); iconView.setImageDrawable(result.icon); @@ -50,6 +49,7 @@ public class IntentSearchViewHolder extends SearchViewHolder { itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + fragment.onSearchResultClicked(); fragment.startActivity(((IntentPayload) result.payload).intent); } }); diff --git a/src/com/android/settings/search2/SearchFragment.java b/src/com/android/settings/search2/SearchFragment.java index 1a4e6dcdbd7..757a0e2ac0c 100644 --- a/src/com/android/settings/search2/SearchFragment.java +++ b/src/com/android/settings/search2/SearchFragment.java @@ -35,23 +35,33 @@ import android.widget.SearchView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; +import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; import java.util.List; public class SearchFragment extends InstrumentedFragment implements SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks> { + private static final String TAG = "SearchFragment"; // State values - static final String STATE_QUERY = "query"; + private static final String STATE_QUERY = "state_query"; + private static final String STATE_NEVER_ENTERED_QUERY = "state_never_entered_query"; + private static final String STATE_RESULT_CLICK_COUNT = "state_result_click_count"; // Loader IDs private static final int LOADER_ID_DATABASE = 0; private static final int LOADER_ID_INSTALLED_APPS = 1; - @VisibleForTesting - String mQuery; + // Logging + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + static final String RESULT_CLICK_COUNT = "settings_search_result_click_count"; + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + String mQuery; + private boolean mNeverEnteredQuery = true; + private int mResultClickCount; + private MetricsFeatureProvider mMetricsFeatureProvider; private SearchFeatureProvider mSearchFeatureProvider; private SearchResultsAdapter mSearchAdapter; @@ -65,8 +75,8 @@ public class SearchFragment extends InstrumentedFragment implements @Override public void onAttach(Context context) { super.onAttach(context); - mSearchFeatureProvider = FeatureFactory.getFactory(context) - .getSearchFeatureProvider(); + mSearchFeatureProvider = FeatureFactory.getFactory(context).getSearchFeatureProvider(); + mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } @Override @@ -76,6 +86,8 @@ public class SearchFragment extends InstrumentedFragment implements mSearchAdapter = new SearchResultsAdapter(this); if (savedInstanceState != null) { mQuery = savedInstanceState.getString(STATE_QUERY); + mNeverEnteredQuery = savedInstanceState.getBoolean(STATE_NEVER_ENTERED_QUERY); + mResultClickCount = savedInstanceState.getInt(STATE_RESULT_CLICK_COUNT); final LoaderManager loaderManager = getLoaderManager(); loaderManager.initLoader(LOADER_ID_DATABASE, null, this); loaderManager.initLoader(LOADER_ID_INSTALLED_APPS, null, this); @@ -96,10 +108,25 @@ public class SearchFragment extends InstrumentedFragment implements return view; } + @Override + public void onStop() { + super.onStop(); + final Activity activity = getActivity(); + if (activity != null && activity.isFinishing()) { + mMetricsFeatureProvider.histogram(activity, RESULT_CLICK_COUNT, mResultClickCount); + if (mNeverEnteredQuery) { + mMetricsFeatureProvider.action(activity, + MetricsProto.MetricsEvent.ACTION_LEAVE_SEARCH_RESULT_WITHOUT_QUERY); + } + } + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(STATE_QUERY, mQuery); + outState.putBoolean(STATE_NEVER_ENTERED_QUERY, mNeverEnteredQuery); + outState.putInt(STATE_RESULT_CLICK_COUNT, mResultClickCount); } @Override @@ -107,6 +134,8 @@ public class SearchFragment extends InstrumentedFragment implements if (TextUtils.equals(query, mQuery)) { return true; } + mResultClickCount = 0; + mNeverEnteredQuery = false; mQuery = query; mSearchAdapter.clearResults(); @@ -147,6 +176,10 @@ public class SearchFragment extends InstrumentedFragment implements public void onLoaderReset(Loader> loader) { } + public void onSearchResultClicked() { + mResultClickCount++; + } + private void restartLoaders() { final LoaderManager loaderManager = getLoaderManager(); loaderManager.restartLoader(LOADER_ID_DATABASE, null /* args */, this /* callback */); diff --git a/src/com/android/settings/search2/SearchViewHolder.java b/src/com/android/settings/search2/SearchViewHolder.java index 45ceb3884a5..315ec6514c2 100644 --- a/src/com/android/settings/search2/SearchViewHolder.java +++ b/src/com/android/settings/search2/SearchViewHolder.java @@ -15,7 +15,6 @@ */ package com.android.settings.search2; -import android.app.Fragment; import android.support.v7.widget.RecyclerView; import android.view.View; @@ -30,5 +29,5 @@ public abstract class SearchViewHolder extends RecyclerView.ViewHolder { super(view); } - public abstract void onBind(Fragment fragment, SearchResult result); + public abstract void onBind(SearchFragment fragment, SearchResult result); } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java index efbad2fad6d..b8fe3fcfd4b 100644 --- a/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java +++ b/tests/robotests/src/com/android/settings/search/InlineSwitchViewHolderTest.java @@ -17,7 +17,6 @@ package com.android.settings.search; -import android.app.Fragment; import android.content.Context; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; @@ -28,7 +27,7 @@ import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.search2.InlineSwitchPayload; import com.android.settings.search2.InlineSwitchViewHolder; -import com.android.settings.search2.IntentPayload; +import com.android.settings.search2.SearchFragment; import com.android.settings.search2.SearchResult; import org.junit.Before; @@ -53,7 +52,7 @@ public class InlineSwitchViewHolderTest { private static final String SUMMARY = "summary"; @Mock - private Fragment mFragment; + private SearchFragment mFragment; @Mock private InlineSwitchPayload mPayload; @@ -97,7 +96,7 @@ public class InlineSwitchViewHolderTest { .addSummary(SUMMARY) .addRank(1) .addPayload(new InlineSwitchPayload("", 0, null)) - .addBreadcrumbs(new ArrayList()) + .addBreadcrumbs(new ArrayList<>()) .addIcon(mIcon) .addPayload(mPayload); diff --git a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java index ed503d8f6ff..3874479fcb4 100644 --- a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java +++ b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java @@ -17,7 +17,6 @@ package com.android.settings.search; -import android.app.Fragment; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -29,6 +28,7 @@ import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.search2.IntentPayload; import com.android.settings.search2.IntentSearchViewHolder; +import com.android.settings.search2.SearchFragment; import com.android.settings.search2.SearchResult; import com.android.settings.search2.SearchResult.Builder; @@ -54,7 +54,7 @@ public class IntentSearchViewHolderTest { private static final String SUMMARY = "summary"; @Mock - private Fragment mFragment; + private SearchFragment mFragment; private IntentSearchViewHolder mHolder; private Drawable mIcon; @@ -84,6 +84,8 @@ public class IntentSearchViewHolderTest { assertThat(mHolder.titleView.getText()).isEqualTo(TITLE); assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY); assertThat(mHolder.iconView.getDrawable()).isEqualTo(mIcon); + + verify(mFragment).onSearchResultClicked(); verify(mFragment).startActivity(any(Intent.class)); } @@ -93,7 +95,7 @@ public class IntentSearchViewHolderTest { .addSummary(SUMMARY) .addRank(1) .addPayload(new IntentPayload(null)) - .addBreadcrumbs(new ArrayList()) + .addBreadcrumbs(new ArrayList<>()) .addIcon(mIcon); return builder.build(); diff --git a/tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java b/tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java index 40d1ae59a11..64d602e502d 100644 --- a/tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java +++ b/tests/robotests/src/com/android/settings/search2/SearchFragmentTest.java @@ -19,6 +19,7 @@ package com.android.settings.search2; import android.content.Context; import android.os.Bundle; +import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; @@ -36,6 +37,8 @@ import org.robolectric.util.ActivityController; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -97,7 +100,14 @@ public class SearchFragmentTest { .findFragmentById(R.id.main_content); fragment.onQueryTextChange(testQuery); + activityController.get().onBackPressed(); + activityController.pause().stop().destroy(); + verify(mFeatureFactory.metricsFeatureProvider, never()).action( + any(Context.class), + eq(MetricsProto.MetricsEvent.ACTION_LEAVE_SEARCH_RESULT_WITHOUT_QUERY)); + verify(mFeatureFactory.metricsFeatureProvider).histogram( + any(Context.class), eq(SearchFragment.RESULT_CLICK_COUNT), eq(0)); verify(mFeatureFactory.searchFeatureProvider) .getDatabaseSearchLoader(any(Context.class), anyString()); verify(mFeatureFactory.searchFeatureProvider)