Add logging for SettingsPanels

The 3 main categories are:
- Panel Opened
- Panel Closed
- Panel Slice interaction

There are 3 close events:
- See more button
- Done button
- Clicking outside the panel

Slice interactions will log the Uri of the Slice and the ActionType,
such as Toggle, Slider, Content (intent).

Change-Id: Iecad948f39f50dd12ae1bcb23a5d523e0df8bb98
Fixes: 117804231
Test: robotests
This commit is contained in:
Matthew Fritze
2019-02-08 14:09:35 -08:00
parent 545f8b1454
commit b197110f71
15 changed files with 291 additions and 42 deletions

View File

@@ -16,6 +16,7 @@
package com.android.settings.panel; package com.android.settings.panel;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -64,4 +65,9 @@ public class InternetConnectivityPanel implements PanelContent {
public Intent getSeeMoreIntent() { public Intent getSeeMoreIntent() {
return new Intent(Settings.ACTION_WIRELESS_SETTINGS); return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
} }
@Override
public int getMetricsCategory() {
return SettingsEnums.PANEL_INTERNET_CONNECTIVITY;
}
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.panel;
import static com.android.settings.media.MediaOutputSlice.MEDIA_PACKAGE_NAME; import static com.android.settings.media.MediaOutputSlice.MEDIA_PACKAGE_NAME;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -71,4 +72,9 @@ public class MediaOutputPanel implements PanelContent {
public Intent getSeeMoreIntent() { public Intent getSeeMoreIntent() {
return null; return null;
} }
@Override
public int getMetricsCategory() {
return SettingsEnums.PANEL_MEDIA_OUTPUT;
}
} }

View File

@@ -50,4 +50,9 @@ public class NfcPanel implements PanelContent {
intent.setClassName(mContext.getPackageName(), SubSettings.class.getName()); intent.setClassName(mContext.getPackageName(), SubSettings.class.getName());
return intent; return intent;
} }
@Override
public int getMetricsCategory() {
return SettingsEnums.PANEL_NFC;
}
} }

View File

@@ -19,12 +19,14 @@ package com.android.settings.panel;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import com.android.settingslib.core.instrumentation.Instrumentable;
import java.util.List; import java.util.List;
/** /**
* Represents the data class needed to create a Settings Panel. See {@link PanelFragment}. * Represents the data class needed to create a Settings Panel. See {@link PanelFragment}.
*/ */
public interface PanelContent { public interface PanelContent extends Instrumentable {
/** /**
* @return a string for the title of the Panel. * @return a string for the title of the Panel.

View File

@@ -21,7 +21,8 @@ import android.content.Context;
public interface PanelFeatureProvider { public interface PanelFeatureProvider {
/** /**
* Returns {@link PanelContent} as specified by the {@code panelType} and {@code packageName}. * Returns {@link PanelContent} as specified by the {@param panelType}, and
* {@param mediaPackageName}.
*/ */
PanelContent getPanel(Context context, String panelType, String packageName); PanelContent getPanel(Context context, String panelType, String mediaPackageName);
} }

View File

@@ -24,7 +24,7 @@ import android.provider.Settings;
public class PanelFeatureProviderImpl implements PanelFeatureProvider { public class PanelFeatureProviderImpl implements PanelFeatureProvider {
@Override @Override
public PanelContent getPanel(Context context, String panelType, String packageName) { public PanelContent getPanel(Context context, String panelType, String mediaPackageName) {
switch (panelType) { switch (panelType) {
case Settings.Panel.ACTION_INTERNET_CONNECTIVITY: case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:
return InternetConnectivityPanel.create(context); return InternetConnectivityPanel.create(context);
@@ -33,7 +33,7 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider {
case Settings.Panel.ACTION_NFC: case Settings.Panel.ACTION_NFC:
return NfcPanel.create(context); return NfcPanel.create(context);
case ACTION_MEDIA_OUTPUT: case ACTION_MEDIA_OUTPUT:
return MediaOutputPanel.create(context, packageName); return MediaOutputPanel.create(context, mediaPackageName);
} }
throw new IllegalStateException("No matching panel for: " + panelType); throw new IllegalStateException("No matching panel for: " + panelType);

View File

@@ -16,9 +16,9 @@
package com.android.settings.panel; package com.android.settings.panel;
import android.content.Intent; import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -35,6 +35,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.panel.PanelLoggingContract.PanelClosedKeys;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class PanelFragment extends Fragment { public class PanelFragment extends Fragment {
@@ -45,15 +47,15 @@ public class PanelFragment extends Fragment {
private Button mDoneButton; private Button mDoneButton;
private RecyclerView mPanelSlices; private RecyclerView mPanelSlices;
private PanelContent mPanel;
private final MetricsFeatureProvider mMetricsProvider;
@VisibleForTesting @VisibleForTesting
PanelSlicesAdapter mAdapter; PanelSlicesAdapter mAdapter;
private View.OnClickListener mDoneButtonListener = (v) -> {
Log.d(TAG, "Closing dialog");
getActivity().finish();
};
public PanelFragment() { public PanelFragment() {
final Context context = getActivity();
mMetricsProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
} }
@Nullable @Nullable
@@ -69,38 +71,70 @@ public class PanelFragment extends Fragment {
mTitleView = view.findViewById(R.id.panel_title); mTitleView = view.findViewById(R.id.panel_title);
final Bundle arguments = getArguments(); final Bundle arguments = getArguments();
final String panelType = arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT); final String panelType =
final String packageName = arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT);
arguments.getString(SettingsPanelActivity.KEY_PANEL_PACKAGE_NAME); final String callingPackageName =
arguments.getString(SettingsPanelActivity.KEY_CALLING_PACKAGE_NAME);
final String mediaPackageName =
arguments.getString(SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME);
final PanelContent panel = FeatureFactory.getFactory(activity) // TODO (b/124399577) transform interface to take a context and bundle.
mPanel = FeatureFactory.getFactory(activity)
.getPanelFeatureProvider() .getPanelFeatureProvider()
.getPanel(activity, panelType, packageName); .getPanel(activity, panelType, mediaPackageName);
mAdapter = new PanelSlicesAdapter(this, panel.getSlices()); // Log panel opened.
mMetricsProvider.action(
0 /* attribution */,
SettingsEnums.PAGE_VISIBLE /* opened panel - Action */,
mPanel.getMetricsCategory(),
callingPackageName,
0 /* value */);
mAdapter = new PanelSlicesAdapter(this, mPanel);
mPanelSlices.setHasFixedSize(true); mPanelSlices.setHasFixedSize(true);
mPanelSlices.setLayoutManager(new LinearLayoutManager((activity))); mPanelSlices.setLayoutManager(new LinearLayoutManager((activity)));
mPanelSlices.setAdapter(mAdapter); mPanelSlices.setAdapter(mAdapter);
mTitleView.setText(panel.getTitle()); mTitleView.setText(mPanel.getTitle());
mSeeMoreButton.setOnClickListener(getSeeMoreListener(panel.getSeeMoreIntent())); mSeeMoreButton.setOnClickListener(getSeeMoreListener());
mDoneButton.setOnClickListener(mDoneButtonListener); mDoneButton.setOnClickListener(getCloseListener());
//If getSeeMoreIntent() is null, hide the mSeeMoreButton. //If getSeeMoreIntent() is null, hide the mSeeMoreButton.
if (panel.getSeeMoreIntent() == null) { if (mPanel.getSeeMoreIntent() == null) {
mSeeMoreButton.setVisibility(View.GONE); mSeeMoreButton.setVisibility(View.GONE);
} }
return view; return view;
} }
private View.OnClickListener getSeeMoreListener(final Intent intent) { @VisibleForTesting
View.OnClickListener getSeeMoreListener() {
return (v) -> { return (v) -> {
mMetricsProvider.action(
0 /* attribution */,
SettingsEnums.PAGE_HIDE ,
mPanel.getMetricsCategory(),
PanelClosedKeys.KEY_SEE_MORE,
0 /* value */);
final FragmentActivity activity = getActivity(); final FragmentActivity activity = getActivity();
activity.startActivity(intent); activity.startActivityForResult(mPanel.getSeeMoreIntent(), 0);
activity.finish(); activity.finish();
}; };
} }
@VisibleForTesting
View.OnClickListener getCloseListener() {
return (v) -> {
mMetricsProvider.action(
0 /* attribution */,
SettingsEnums.PAGE_HIDE,
mPanel.getMetricsCategory(),
PanelClosedKeys.KEY_DONE,
0 /* value */);
getActivity().finish();
};
}
} }

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.panel;
/**
* Simple contract class to track keys in Panel logging.
*
* <p>
* Constants should only be removed if underlying panel, or use case is removed.
* </p>
*/
public class PanelLoggingContract {
/**
* Keys tracking different ways users exit Panels.
*/
interface PanelClosedKeys {
/**
* The user clicked the See More button linking deeper into Settings.
*/
String KEY_SEE_MORE = "see_more";
/**
* The user clicked the Done button, closing the Panel.
*/
String KEY_DONE = "done";
/**
* The user clicked outside the dialog, closing the Panel.
*/
String KEY_CLICKED_OUT = "clicked_out";
}
}

View File

@@ -16,6 +16,7 @@
package com.android.settings.panel; package com.android.settings.panel;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -31,8 +32,8 @@ import androidx.slice.widget.SliceLiveData;
import androidx.slice.widget.SliceView; import androidx.slice.widget.SliceView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -43,10 +44,12 @@ public class PanelSlicesAdapter
private final List<Uri> mSliceUris; private final List<Uri> mSliceUris;
private final PanelFragment mPanelFragment; private final PanelFragment mPanelFragment;
private final PanelContent mPanelContent;
public PanelSlicesAdapter(PanelFragment fragment, List<Uri> sliceUris) { public PanelSlicesAdapter(PanelFragment fragment, PanelContent panel) {
mPanelFragment = fragment; mPanelFragment = fragment;
mSliceUris = new ArrayList<>(sliceUris); mSliceUris = panel.getSlices();
mPanelContent = panel;
} }
@NonNull @NonNull
@@ -56,7 +59,7 @@ public class PanelSlicesAdapter
final LayoutInflater inflater = LayoutInflater.from(context); final LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false); final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
return new SliceRowViewHolder(view); return new SliceRowViewHolder(view, mPanelContent);
} }
@Override @Override
@@ -79,22 +82,38 @@ public class PanelSlicesAdapter
*/ */
public static class SliceRowViewHolder extends RecyclerView.ViewHolder { public static class SliceRowViewHolder extends RecyclerView.ViewHolder {
private final PanelContent mPanelContent;
@VisibleForTesting @VisibleForTesting
LiveData<Slice> sliceLiveData; LiveData<Slice> sliceLiveData;
@VisibleForTesting @VisibleForTesting
final SliceView sliceView; final SliceView sliceView;
public SliceRowViewHolder(View view) { public SliceRowViewHolder(View view, PanelContent panelContent) {
super(view); super(view);
sliceView = view.findViewById(R.id.slice_view); sliceView = view.findViewById(R.id.slice_view);
sliceView.setMode(SliceView.MODE_LARGE); sliceView.setMode(SliceView.MODE_LARGE);
mPanelContent = panelContent;
} }
public void onBind(PanelFragment fragment, Uri sliceUri) { public void onBind(PanelFragment fragment, Uri sliceUri) {
final Context context = sliceView.getContext(); final Context context = sliceView.getContext();
sliceLiveData = SliceLiveData.fromUri(context, sliceUri); sliceLiveData = SliceLiveData.fromUri(context, sliceUri);
sliceLiveData.observe(fragment.getViewLifecycleOwner(), sliceView); sliceLiveData.observe(fragment.getViewLifecycleOwner(), sliceView);
// Log Panel interaction
sliceView.setOnSliceActionListener(
((eventInfo, sliceItem) -> {
FeatureFactory.getFactory(context)
.getMetricsFeatureProvider()
.action(0 /* attribution */,
SettingsEnums.ACTION_PANEL_INTERACTION,
mPanelContent.getMetricsCategory(),
sliceUri.toString() /* log key */,
eventInfo.actionType /* value */);
})
);
} }
} }
} }

View File

@@ -19,11 +19,13 @@ package com.android.settings.panel;
import static com.android.settingslib.media.MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT; import static com.android.settingslib.media.MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT;
import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACKAGE_NAME; import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACKAGE_NAME;
import android.app.settings.SettingsEnums;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
@@ -34,6 +36,8 @@ import androidx.fragment.app.FragmentManager;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.panel.PanelLoggingContract.PanelClosedKeys;
/** /**
* Dialog Activity to host Settings Slices. * Dialog Activity to host Settings Slices.
@@ -49,7 +53,16 @@ public class SettingsPanelActivity extends FragmentActivity {
* Key specifying which Panel the app is requesting. * Key specifying which Panel the app is requesting.
*/ */
public static final String KEY_PANEL_TYPE_ARGUMENT = "PANEL_TYPE_ARGUMENT"; public static final String KEY_PANEL_TYPE_ARGUMENT = "PANEL_TYPE_ARGUMENT";
public static final String KEY_PANEL_PACKAGE_NAME = "PANEL_PACKAGE_NAME";
/**
* Key specifying the package which requested the Panel.
*/
public static final String KEY_CALLING_PACKAGE_NAME = "PANEL_CALLING_PACKAGE_NAME";
/**
* Key specifying the package name for which the
*/
public static final String KEY_MEDIA_PACKAGE_NAME = "PANEL_MEDIA_PACKAGE_NAME";
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -62,12 +75,12 @@ public class SettingsPanelActivity extends FragmentActivity {
return; return;
} }
final String packageName = final String mediaPackageName =
callingIntent.getStringExtra(EXTRA_PACKAGE_NAME); callingIntent.getStringExtra(EXTRA_PACKAGE_NAME);
if (TextUtils.equals(ACTION_MEDIA_OUTPUT, callingIntent.getAction()) if (TextUtils.equals(ACTION_MEDIA_OUTPUT, callingIntent.getAction())
&& TextUtils.isEmpty(packageName)) { && TextUtils.isEmpty(mediaPackageName)) {
Log.e(TAG, "Null package name, closing Panel Activity"); Log.e(TAG, "Missing EXTRA_PACKAGE_NAME, closing Panel Activity");
finish(); finish();
return; return;
} }
@@ -81,7 +94,8 @@ public class SettingsPanelActivity extends FragmentActivity {
WindowManager.LayoutParams.WRAP_CONTENT); WindowManager.LayoutParams.WRAP_CONTENT);
mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, callingIntent.getAction()); mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, callingIntent.getAction());
mBundle.putString(KEY_PANEL_PACKAGE_NAME, packageName); mBundle.putString(KEY_CALLING_PACKAGE_NAME, getCallingPackage());
mBundle.putString(KEY_MEDIA_PACKAGE_NAME, mediaPackageName);
final PanelFragment panelFragment = new PanelFragment(); final PanelFragment panelFragment = new PanelFragment();
panelFragment.setArguments(mBundle); panelFragment.setArguments(mBundle);
@@ -92,4 +106,21 @@ public class SettingsPanelActivity extends FragmentActivity {
fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit(); fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit();
} }
} }
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
final PanelContent panelContent = FeatureFactory.getFactory(this)
.getPanelFeatureProvider()
.getPanel(this, getIntent().getAction(), null /* Media Package Name */);
FeatureFactory.getFactory(this)
.getMetricsFeatureProvider()
.action(0 /* attribution */,
SettingsEnums.PAGE_HIDE,
panelContent.getMetricsCategory(),
PanelClosedKeys.KEY_CLICKED_OUT,
0 /* value */);
}
return super.onTouchEvent(event);
}
} }

View File

@@ -21,6 +21,7 @@ import static com.android.settings.slices.CustomSliceRegistry.VOLUME_CALL_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI; import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI;
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI; import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -62,4 +63,9 @@ public class VolumePanel implements PanelContent {
public Intent getSeeMoreIntent() { public Intent getSeeMoreIntent() {
return new Intent(Settings.ACTION_SOUND_SETTINGS); return new Intent(Settings.ACTION_SOUND_SETTINGS);
} }
@Override
public int getMetricsCategory() {
return SettingsEnums.PANEL_VOLUME;
}
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.panel;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import android.app.settings.SettingsEnums;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -53,4 +54,9 @@ public class FakePanelContent implements PanelContent {
public Intent getSeeMoreIntent() { public Intent getSeeMoreIntent() {
return INTENT; return INTENT;
} }
@Override
public int getMetricsCategory() {
return SettingsEnums.TESTING;
}
} }

View File

@@ -22,10 +22,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import com.android.settings.R; import com.android.settings.R;
@@ -71,13 +74,14 @@ public class PanelFragmentTest {
.get() .get()
.getSupportFragmentManager() .getSupportFragmentManager()
.findFragmentById(R.id.main_content)); .findFragmentById(R.id.main_content));
final Bundle bundle = new Bundle();
bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
doReturn(bundle).when(mPanelFragment).getArguments();
} }
@Test @Test
public void onCreateView_adapterGetsDataset() { public void onCreateView_adapterGetsDataset() {
final Bundle bundle = new Bundle();
bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
doReturn(bundle).when(mPanelFragment).getArguments();
mPanelFragment.onCreateView(LayoutInflater.from(mContext), mPanelFragment.onCreateView(LayoutInflater.from(mContext),
new LinearLayout(mContext), null); new LinearLayout(mContext), null);
PanelSlicesAdapter adapter = mPanelFragment.mAdapter; PanelSlicesAdapter adapter = mPanelFragment.mAdapter;
@@ -85,4 +89,43 @@ public class PanelFragmentTest {
assertThat(adapter.getData()).containsAllIn(mFakePanelContent.getSlices()); assertThat(adapter.getData()).containsAllIn(mFakePanelContent.getSlices());
} }
@Test
public void onCreate_logsOpenEvent() {
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_VISIBLE,
mFakePanelContent.getMetricsCategory(),
null,
0);
}
@Test
public void panelSeeMoreClick_logsCloseEvent() {
final View.OnClickListener listener = mPanelFragment.getSeeMoreListener();
listener.onClick(null);
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_HIDE,
mFakePanelContent.getMetricsCategory(),
PanelLoggingContract.PanelClosedKeys.KEY_SEE_MORE,
0
);
}
@Test
public void panelDoneClick_logsCloseEvent() {
final View.OnClickListener listener = mPanelFragment.getCloseListener();
listener.onClick(null);
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_HIDE,
mFakePanelContent.getMetricsCategory(),
PanelLoggingContract.PanelClosedKeys.KEY_DONE,
0
);
}
} }

View File

@@ -71,7 +71,7 @@ public class PanelSlicesAdapterTest {
.getSupportFragmentManager() .getSupportFragmentManager()
.findFragmentById(R.id.main_content)); .findFragmentById(R.id.main_content));
mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent.getSlices()); mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent);
} }
@Test @Test

View File

@@ -16,13 +16,25 @@
package com.android.settings.panel; package com.android.settings.panel;
import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_PACKAGE_NAME; import static com.android.settings.panel.SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME;
import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT; import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.content.Intent; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.view.MotionEvent;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
@@ -31,6 +43,22 @@ import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class SettingsPanelActivityTest { public class SettingsPanelActivityTest {
private FakeFeatureFactory mFakeFeatureFactory;
private FakeSettingsPanelActivity mSettingsPanelActivity;
private PanelFeatureProvider mPanelFeatureProvider;
private FakePanelContent mFakePanelContent;
@Before
public void setUp() {
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mSettingsPanelActivity = Robolectric.buildActivity(FakeSettingsPanelActivity.class)
.create().get();
mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
mFakePanelContent = new FakePanelContent();
doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any(), any());
}
@Test @Test
public void startMediaOutputSlice_withPackageName_bundleShouldHaveValue() { public void startMediaOutputSlice_withPackageName_bundleShouldHaveValue() {
final Intent intent = new Intent() final Intent intent = new Intent()
@@ -41,7 +69,7 @@ public class SettingsPanelActivityTest {
final SettingsPanelActivity activity = final SettingsPanelActivity activity =
Robolectric.buildActivity(SettingsPanelActivity.class, intent).create().get(); Robolectric.buildActivity(SettingsPanelActivity.class, intent).create().get();
assertThat(activity.mBundle.getString(KEY_PANEL_PACKAGE_NAME)) assertThat(activity.mBundle.getString(KEY_MEDIA_PACKAGE_NAME))
.isEqualTo("com.google.android.music"); .isEqualTo("com.google.android.music");
assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT)) assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
.isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT"); .isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
@@ -55,7 +83,23 @@ public class SettingsPanelActivityTest {
final SettingsPanelActivity activity = final SettingsPanelActivity activity =
Robolectric.buildActivity(SettingsPanelActivity.class, intent).create().get(); Robolectric.buildActivity(SettingsPanelActivity.class, intent).create().get();
assertThat(activity.mBundle.containsKey(KEY_PANEL_PACKAGE_NAME)).isFalse(); assertThat(activity.mBundle.containsKey(KEY_MEDIA_PACKAGE_NAME)).isFalse();
assertThat(activity.mBundle.containsKey(KEY_PANEL_TYPE_ARGUMENT)).isFalse(); assertThat(activity.mBundle.containsKey(KEY_PANEL_TYPE_ARGUMENT)).isFalse();
} }
@Test
public void onTouchEvent_outsideAction_logsPanelClosed() {
final MotionEvent event = mock(MotionEvent.class);
when(event.getAction()).thenReturn(MotionEvent.ACTION_OUTSIDE);
mSettingsPanelActivity.onTouchEvent(event);
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_HIDE,
SettingsEnums.TESTING,
PanelLoggingContract.PanelClosedKeys.KEY_CLICKED_OUT,
0
);
}
} }