Add logging to search fragment.
- User leaves screen without any query - Number of results clicked before leaving screen - Event of each result click Bug: 34204146 Test: RunSettingsRoboTests Change-Id: I357fbb4cdfd4d02370791b4a2ddeb2127fdddf97
This commit is contained in:
@@ -17,14 +17,11 @@
|
|||||||
|
|
||||||
package com.android.settings.search2;
|
package com.android.settings.search2;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewParent;
|
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.android.internal.widget.PreferenceImageView;
|
import com.android.internal.widget.PreferenceImageView;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -52,7 +49,7 @@ public class InlineSwitchViewHolder extends SearchViewHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(Fragment fragment, SearchResult result) {
|
public void onBind(SearchFragment fragment, SearchResult result) {
|
||||||
if (mContext == null) {
|
if (mContext == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -62,6 +59,7 @@ public class InlineSwitchViewHolder extends SearchViewHolder {
|
|||||||
switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
fragment.onSearchResultClicked();
|
||||||
payload.setSwitchValue(mContext, isChecked);
|
payload.setSwitchValue(mContext, isChecked);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.search2;
|
package com.android.settings.search2;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -40,7 +39,7 @@ public class IntentSearchViewHolder extends SearchViewHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBind(final Fragment fragment, final SearchResult result) {
|
public void onBind(final SearchFragment fragment, final SearchResult result) {
|
||||||
titleView.setText(result.title);
|
titleView.setText(result.title);
|
||||||
summaryView.setText(result.summary);
|
summaryView.setText(result.summary);
|
||||||
iconView.setImageDrawable(result.icon);
|
iconView.setImageDrawable(result.icon);
|
||||||
@@ -50,6 +49,7 @@ public class IntentSearchViewHolder extends SearchViewHolder {
|
|||||||
itemView.setOnClickListener(new View.OnClickListener() {
|
itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
fragment.onSearchResultClicked();
|
||||||
fragment.startActivity(((IntentPayload) result.payload).intent);
|
fragment.startActivity(((IntentPayload) result.payload).intent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -35,23 +35,33 @@ import android.widget.SearchView;
|
|||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.InstrumentedFragment;
|
import com.android.settings.core.InstrumentedFragment;
|
||||||
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SearchFragment extends InstrumentedFragment implements
|
public class SearchFragment extends InstrumentedFragment implements
|
||||||
SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<List<SearchResult>> {
|
SearchView.OnQueryTextListener, LoaderManager.LoaderCallbacks<List<SearchResult>> {
|
||||||
|
private static final String TAG = "SearchFragment";
|
||||||
|
|
||||||
// State values
|
// 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
|
// Loader IDs
|
||||||
private static final int LOADER_ID_DATABASE = 0;
|
private static final int LOADER_ID_DATABASE = 0;
|
||||||
private static final int LOADER_ID_INSTALLED_APPS = 1;
|
private static final int LOADER_ID_INSTALLED_APPS = 1;
|
||||||
|
|
||||||
@VisibleForTesting
|
// Logging
|
||||||
String mQuery;
|
@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 SearchFeatureProvider mSearchFeatureProvider;
|
||||||
|
|
||||||
private SearchResultsAdapter mSearchAdapter;
|
private SearchResultsAdapter mSearchAdapter;
|
||||||
@@ -65,8 +75,8 @@ public class SearchFragment extends InstrumentedFragment implements
|
|||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
mSearchFeatureProvider = FeatureFactory.getFactory(context)
|
mSearchFeatureProvider = FeatureFactory.getFactory(context).getSearchFeatureProvider();
|
||||||
.getSearchFeatureProvider();
|
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,6 +86,8 @@ public class SearchFragment extends InstrumentedFragment implements
|
|||||||
mSearchAdapter = new SearchResultsAdapter(this);
|
mSearchAdapter = new SearchResultsAdapter(this);
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
mQuery = savedInstanceState.getString(STATE_QUERY);
|
mQuery = savedInstanceState.getString(STATE_QUERY);
|
||||||
|
mNeverEnteredQuery = savedInstanceState.getBoolean(STATE_NEVER_ENTERED_QUERY);
|
||||||
|
mResultClickCount = savedInstanceState.getInt(STATE_RESULT_CLICK_COUNT);
|
||||||
final LoaderManager loaderManager = getLoaderManager();
|
final LoaderManager loaderManager = getLoaderManager();
|
||||||
loaderManager.initLoader(LOADER_ID_DATABASE, null, this);
|
loaderManager.initLoader(LOADER_ID_DATABASE, null, this);
|
||||||
loaderManager.initLoader(LOADER_ID_INSTALLED_APPS, null, this);
|
loaderManager.initLoader(LOADER_ID_INSTALLED_APPS, null, this);
|
||||||
@@ -96,10 +108,25 @@ public class SearchFragment extends InstrumentedFragment implements
|
|||||||
return view;
|
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
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
outState.putString(STATE_QUERY, mQuery);
|
outState.putString(STATE_QUERY, mQuery);
|
||||||
|
outState.putBoolean(STATE_NEVER_ENTERED_QUERY, mNeverEnteredQuery);
|
||||||
|
outState.putInt(STATE_RESULT_CLICK_COUNT, mResultClickCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -107,6 +134,8 @@ public class SearchFragment extends InstrumentedFragment implements
|
|||||||
if (TextUtils.equals(query, mQuery)) {
|
if (TextUtils.equals(query, mQuery)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
mResultClickCount = 0;
|
||||||
|
mNeverEnteredQuery = false;
|
||||||
mQuery = query;
|
mQuery = query;
|
||||||
mSearchAdapter.clearResults();
|
mSearchAdapter.clearResults();
|
||||||
|
|
||||||
@@ -147,6 +176,10 @@ public class SearchFragment extends InstrumentedFragment implements
|
|||||||
public void onLoaderReset(Loader<List<SearchResult>> loader) {
|
public void onLoaderReset(Loader<List<SearchResult>> loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onSearchResultClicked() {
|
||||||
|
mResultClickCount++;
|
||||||
|
}
|
||||||
|
|
||||||
private void restartLoaders() {
|
private void restartLoaders() {
|
||||||
final LoaderManager loaderManager = getLoaderManager();
|
final LoaderManager loaderManager = getLoaderManager();
|
||||||
loaderManager.restartLoader(LOADER_ID_DATABASE, null /* args */, this /* callback */);
|
loaderManager.restartLoader(LOADER_ID_DATABASE, null /* args */, this /* callback */);
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.search2;
|
package com.android.settings.search2;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -30,5 +29,5 @@ public abstract class SearchViewHolder extends RecyclerView.ViewHolder {
|
|||||||
super(view);
|
super(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onBind(Fragment fragment, SearchResult result);
|
public abstract void onBind(SearchFragment fragment, SearchResult result);
|
||||||
}
|
}
|
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package com.android.settings.search;
|
package com.android.settings.search;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -28,7 +27,7 @@ import com.android.settings.SettingsRobolectricTestRunner;
|
|||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.search2.InlineSwitchPayload;
|
import com.android.settings.search2.InlineSwitchPayload;
|
||||||
import com.android.settings.search2.InlineSwitchViewHolder;
|
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 com.android.settings.search2.SearchResult;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -53,7 +52,7 @@ public class InlineSwitchViewHolderTest {
|
|||||||
private static final String SUMMARY = "summary";
|
private static final String SUMMARY = "summary";
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Fragment mFragment;
|
private SearchFragment mFragment;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private InlineSwitchPayload mPayload;
|
private InlineSwitchPayload mPayload;
|
||||||
@@ -97,7 +96,7 @@ public class InlineSwitchViewHolderTest {
|
|||||||
.addSummary(SUMMARY)
|
.addSummary(SUMMARY)
|
||||||
.addRank(1)
|
.addRank(1)
|
||||||
.addPayload(new InlineSwitchPayload("", 0, null))
|
.addPayload(new InlineSwitchPayload("", 0, null))
|
||||||
.addBreadcrumbs(new ArrayList<String>())
|
.addBreadcrumbs(new ArrayList<>())
|
||||||
.addIcon(mIcon)
|
.addIcon(mIcon)
|
||||||
.addPayload(mPayload);
|
.addPayload(mPayload);
|
||||||
|
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package com.android.settings.search;
|
package com.android.settings.search;
|
||||||
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -29,6 +28,7 @@ import com.android.settings.SettingsRobolectricTestRunner;
|
|||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.search2.IntentPayload;
|
import com.android.settings.search2.IntentPayload;
|
||||||
import com.android.settings.search2.IntentSearchViewHolder;
|
import com.android.settings.search2.IntentSearchViewHolder;
|
||||||
|
import com.android.settings.search2.SearchFragment;
|
||||||
import com.android.settings.search2.SearchResult;
|
import com.android.settings.search2.SearchResult;
|
||||||
import com.android.settings.search2.SearchResult.Builder;
|
import com.android.settings.search2.SearchResult.Builder;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class IntentSearchViewHolderTest {
|
|||||||
private static final String SUMMARY = "summary";
|
private static final String SUMMARY = "summary";
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Fragment mFragment;
|
private SearchFragment mFragment;
|
||||||
private IntentSearchViewHolder mHolder;
|
private IntentSearchViewHolder mHolder;
|
||||||
private Drawable mIcon;
|
private Drawable mIcon;
|
||||||
|
|
||||||
@@ -84,6 +84,8 @@ public class IntentSearchViewHolderTest {
|
|||||||
assertThat(mHolder.titleView.getText()).isEqualTo(TITLE);
|
assertThat(mHolder.titleView.getText()).isEqualTo(TITLE);
|
||||||
assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
|
assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
|
||||||
assertThat(mHolder.iconView.getDrawable()).isEqualTo(mIcon);
|
assertThat(mHolder.iconView.getDrawable()).isEqualTo(mIcon);
|
||||||
|
|
||||||
|
verify(mFragment).onSearchResultClicked();
|
||||||
verify(mFragment).startActivity(any(Intent.class));
|
verify(mFragment).startActivity(any(Intent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ public class IntentSearchViewHolderTest {
|
|||||||
.addSummary(SUMMARY)
|
.addSummary(SUMMARY)
|
||||||
.addRank(1)
|
.addRank(1)
|
||||||
.addPayload(new IntentPayload(null))
|
.addPayload(new IntentPayload(null))
|
||||||
.addBreadcrumbs(new ArrayList<String>())
|
.addBreadcrumbs(new ArrayList<>())
|
||||||
.addIcon(mIcon);
|
.addIcon(mIcon);
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
@@ -19,6 +19,7 @@ package com.android.settings.search2;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsRobolectricTestRunner;
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
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.any;
|
||||||
import static org.mockito.Matchers.anyString;
|
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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -97,7 +100,14 @@ public class SearchFragmentTest {
|
|||||||
.findFragmentById(R.id.main_content);
|
.findFragmentById(R.id.main_content);
|
||||||
|
|
||||||
fragment.onQueryTextChange(testQuery);
|
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)
|
verify(mFeatureFactory.searchFeatureProvider)
|
||||||
.getDatabaseSearchLoader(any(Context.class), anyString());
|
.getDatabaseSearchLoader(any(Context.class), anyString());
|
||||||
verify(mFeatureFactory.searchFeatureProvider)
|
verify(mFeatureFactory.searchFeatureProvider)
|
||||||
|
Reference in New Issue
Block a user