diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java index d20b75afce4..4e4fc0cd4f8 100644 --- a/src/com/android/settings/panel/InternetConnectivityPanel.java +++ b/src/com/android/settings/panel/InternetConnectivityPanel.java @@ -16,6 +16,7 @@ package com.android.settings.panel; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -64,4 +65,9 @@ public class InternetConnectivityPanel implements PanelContent { public Intent getSeeMoreIntent() { return new Intent(Settings.ACTION_WIRELESS_SETTINGS); } + + @Override + public int getMetricsCategory() { + return SettingsEnums.PANEL_INTERNET_CONNECTIVITY; + } } diff --git a/src/com/android/settings/panel/MediaOutputPanel.java b/src/com/android/settings/panel/MediaOutputPanel.java index f7639d94a78..c42906d1302 100644 --- a/src/com/android/settings/panel/MediaOutputPanel.java +++ b/src/com/android/settings/panel/MediaOutputPanel.java @@ -19,6 +19,7 @@ package com.android.settings.panel; import static com.android.settings.media.MediaOutputSlice.MEDIA_PACKAGE_NAME; import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_SLICE_URI; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -71,4 +72,9 @@ public class MediaOutputPanel implements PanelContent { public Intent getSeeMoreIntent() { return null; } + + @Override + public int getMetricsCategory() { + return SettingsEnums.PANEL_MEDIA_OUTPUT; + } } diff --git a/src/com/android/settings/panel/NfcPanel.java b/src/com/android/settings/panel/NfcPanel.java index 70452a364df..8fa41d9d303 100644 --- a/src/com/android/settings/panel/NfcPanel.java +++ b/src/com/android/settings/panel/NfcPanel.java @@ -50,4 +50,9 @@ public class NfcPanel implements PanelContent { intent.setClassName(mContext.getPackageName(), SubSettings.class.getName()); return intent; } + + @Override + public int getMetricsCategory() { + return SettingsEnums.PANEL_NFC; + } } diff --git a/src/com/android/settings/panel/PanelContent.java b/src/com/android/settings/panel/PanelContent.java index bd84c2fa617..496bac3f120 100644 --- a/src/com/android/settings/panel/PanelContent.java +++ b/src/com/android/settings/panel/PanelContent.java @@ -19,12 +19,14 @@ package com.android.settings.panel; import android.content.Intent; import android.net.Uri; +import com.android.settingslib.core.instrumentation.Instrumentable; + import java.util.List; /** * 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. diff --git a/src/com/android/settings/panel/PanelFeatureProvider.java b/src/com/android/settings/panel/PanelFeatureProvider.java index 5af5ac8979b..85e098d603c 100644 --- a/src/com/android/settings/panel/PanelFeatureProvider.java +++ b/src/com/android/settings/panel/PanelFeatureProvider.java @@ -21,7 +21,8 @@ import android.content.Context; 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); } diff --git a/src/com/android/settings/panel/PanelFeatureProviderImpl.java b/src/com/android/settings/panel/PanelFeatureProviderImpl.java index c3d611dc515..6b096a15b64 100644 --- a/src/com/android/settings/panel/PanelFeatureProviderImpl.java +++ b/src/com/android/settings/panel/PanelFeatureProviderImpl.java @@ -24,7 +24,7 @@ import android.provider.Settings; public class PanelFeatureProviderImpl implements PanelFeatureProvider { @Override - public PanelContent getPanel(Context context, String panelType, String packageName) { + public PanelContent getPanel(Context context, String panelType, String mediaPackageName) { switch (panelType) { case Settings.Panel.ACTION_INTERNET_CONNECTIVITY: return InternetConnectivityPanel.create(context); @@ -33,7 +33,7 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider { case Settings.Panel.ACTION_NFC: return NfcPanel.create(context); case ACTION_MEDIA_OUTPUT: - return MediaOutputPanel.create(context, packageName); + return MediaOutputPanel.create(context, mediaPackageName); } throw new IllegalStateException("No matching panel for: " + panelType); diff --git a/src/com/android/settings/panel/PanelFragment.java b/src/com/android/settings/panel/PanelFragment.java index db0bf0e85ac..a222d36e7b8 100644 --- a/src/com/android/settings/panel/PanelFragment.java +++ b/src/com/android/settings/panel/PanelFragment.java @@ -16,9 +16,9 @@ package com.android.settings.panel; -import android.content.Intent; +import android.app.settings.SettingsEnums; +import android.content.Context; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -35,6 +35,8 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; 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 { @@ -45,15 +47,15 @@ public class PanelFragment extends Fragment { private Button mDoneButton; private RecyclerView mPanelSlices; + private PanelContent mPanel; + private final MetricsFeatureProvider mMetricsProvider; + @VisibleForTesting PanelSlicesAdapter mAdapter; - private View.OnClickListener mDoneButtonListener = (v) -> { - Log.d(TAG, "Closing dialog"); - getActivity().finish(); - }; - public PanelFragment() { + final Context context = getActivity(); + mMetricsProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } @Nullable @@ -69,38 +71,70 @@ public class PanelFragment extends Fragment { mTitleView = view.findViewById(R.id.panel_title); final Bundle arguments = getArguments(); - final String panelType = arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT); - final String packageName = - arguments.getString(SettingsPanelActivity.KEY_PANEL_PACKAGE_NAME); + final String panelType = + arguments.getString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT); + 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() - .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.setLayoutManager(new LinearLayoutManager((activity))); mPanelSlices.setAdapter(mAdapter); - mTitleView.setText(panel.getTitle()); + mTitleView.setText(mPanel.getTitle()); - mSeeMoreButton.setOnClickListener(getSeeMoreListener(panel.getSeeMoreIntent())); - mDoneButton.setOnClickListener(mDoneButtonListener); + mSeeMoreButton.setOnClickListener(getSeeMoreListener()); + mDoneButton.setOnClickListener(getCloseListener()); //If getSeeMoreIntent() is null, hide the mSeeMoreButton. - if (panel.getSeeMoreIntent() == null) { + if (mPanel.getSeeMoreIntent() == null) { mSeeMoreButton.setVisibility(View.GONE); } return view; } - private View.OnClickListener getSeeMoreListener(final Intent intent) { + @VisibleForTesting + View.OnClickListener getSeeMoreListener() { return (v) -> { + mMetricsProvider.action( + 0 /* attribution */, + SettingsEnums.PAGE_HIDE , + mPanel.getMetricsCategory(), + PanelClosedKeys.KEY_SEE_MORE, + 0 /* value */); final FragmentActivity activity = getActivity(); - activity.startActivity(intent); + activity.startActivityForResult(mPanel.getSeeMoreIntent(), 0); activity.finish(); }; } + + @VisibleForTesting + View.OnClickListener getCloseListener() { + return (v) -> { + mMetricsProvider.action( + 0 /* attribution */, + SettingsEnums.PAGE_HIDE, + mPanel.getMetricsCategory(), + PanelClosedKeys.KEY_DONE, + 0 /* value */); + getActivity().finish(); + }; + } } diff --git a/src/com/android/settings/panel/PanelLoggingContract.java b/src/com/android/settings/panel/PanelLoggingContract.java new file mode 100644 index 00000000000..e14918648fd --- /dev/null +++ b/src/com/android/settings/panel/PanelLoggingContract.java @@ -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. + * + *

+ * Constants should only be removed if underlying panel, or use case is removed. + *

+ */ +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"; + } +} diff --git a/src/com/android/settings/panel/PanelSlicesAdapter.java b/src/com/android/settings/panel/PanelSlicesAdapter.java index f688512eab1..c1cb0499d36 100644 --- a/src/com/android/settings/panel/PanelSlicesAdapter.java +++ b/src/com/android/settings/panel/PanelSlicesAdapter.java @@ -16,6 +16,7 @@ package com.android.settings.panel; +import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.view.LayoutInflater; @@ -31,8 +32,8 @@ import androidx.slice.widget.SliceLiveData; import androidx.slice.widget.SliceView; import com.android.settings.R; +import com.android.settings.overlay.FeatureFactory; -import java.util.ArrayList; import java.util.List; /** @@ -43,10 +44,12 @@ public class PanelSlicesAdapter private final List mSliceUris; private final PanelFragment mPanelFragment; + private final PanelContent mPanelContent; - public PanelSlicesAdapter(PanelFragment fragment, List sliceUris) { + public PanelSlicesAdapter(PanelFragment fragment, PanelContent panel) { mPanelFragment = fragment; - mSliceUris = new ArrayList<>(sliceUris); + mSliceUris = panel.getSlices(); + mPanelContent = panel; } @NonNull @@ -56,7 +59,7 @@ public class PanelSlicesAdapter final LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false); - return new SliceRowViewHolder(view); + return new SliceRowViewHolder(view, mPanelContent); } @Override @@ -79,22 +82,38 @@ public class PanelSlicesAdapter */ public static class SliceRowViewHolder extends RecyclerView.ViewHolder { + private final PanelContent mPanelContent; + @VisibleForTesting LiveData sliceLiveData; @VisibleForTesting final SliceView sliceView; - public SliceRowViewHolder(View view) { + public SliceRowViewHolder(View view, PanelContent panelContent) { super(view); sliceView = view.findViewById(R.id.slice_view); sliceView.setMode(SliceView.MODE_LARGE); + mPanelContent = panelContent; } public void onBind(PanelFragment fragment, Uri sliceUri) { final Context context = sliceView.getContext(); sliceLiveData = SliceLiveData.fromUri(context, sliceUri); 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 */); + }) + ); } } } diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java index 4cf535ede11..3819c80a64c 100644 --- a/src/com/android/settings/panel/SettingsPanelActivity.java +++ b/src/com/android/settings/panel/SettingsPanelActivity.java @@ -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.EXTRA_PACKAGE_NAME; +import android.app.settings.SettingsEnums; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; +import android.view.MotionEvent; import android.view.Window; import android.view.WindowManager; @@ -34,6 +36,8 @@ import androidx.fragment.app.FragmentManager; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; +import com.android.settings.overlay.FeatureFactory; +import com.android.settings.panel.PanelLoggingContract.PanelClosedKeys; /** * Dialog Activity to host Settings Slices. @@ -49,7 +53,16 @@ public class SettingsPanelActivity extends FragmentActivity { * 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_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 protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -62,12 +75,12 @@ public class SettingsPanelActivity extends FragmentActivity { return; } - final String packageName = + final String mediaPackageName = callingIntent.getStringExtra(EXTRA_PACKAGE_NAME); if (TextUtils.equals(ACTION_MEDIA_OUTPUT, callingIntent.getAction()) - && TextUtils.isEmpty(packageName)) { - Log.e(TAG, "Null package name, closing Panel Activity"); + && TextUtils.isEmpty(mediaPackageName)) { + Log.e(TAG, "Missing EXTRA_PACKAGE_NAME, closing Panel Activity"); finish(); return; } @@ -81,7 +94,8 @@ public class SettingsPanelActivity extends FragmentActivity { WindowManager.LayoutParams.WRAP_CONTENT); 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(); panelFragment.setArguments(mBundle); @@ -92,4 +106,21 @@ public class SettingsPanelActivity extends FragmentActivity { 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); + } } diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java index 352fed558d7..20c2272a2a6 100644 --- a/src/com/android/settings/panel/VolumePanel.java +++ b/src/com/android/settings/panel/VolumePanel.java @@ -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_RINGER_URI; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -62,4 +63,9 @@ public class VolumePanel implements PanelContent { public Intent getSeeMoreIntent() { return new Intent(Settings.ACTION_SOUND_SETTINGS); } + + @Override + public int getMetricsCategory() { + return SettingsEnums.PANEL_VOLUME; + } } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java index 1d799529922..8f541154604 100644 --- a/tests/robotests/src/com/android/settings/panel/FakePanelContent.java +++ b/tests/robotests/src/com/android/settings/panel/FakePanelContent.java @@ -18,6 +18,7 @@ package com.android.settings.panel; import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; +import android.app.settings.SettingsEnums; import android.content.Intent; import android.net.Uri; @@ -53,4 +54,9 @@ public class FakePanelContent implements PanelContent { public Intent getSeeMoreIntent() { return INTENT; } + + @Override + public int getMetricsCategory() { + return SettingsEnums.TESTING; + } } diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java index 389c31e621c..be8d8bc72b4 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java +++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java @@ -22,10 +22,13 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.View; import android.widget.LinearLayout; import com.android.settings.R; @@ -71,13 +74,14 @@ public class PanelFragmentTest { .get() .getSupportFragmentManager() .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 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), new LinearLayout(mContext), null); PanelSlicesAdapter adapter = mPanelFragment.mAdapter; @@ -85,4 +89,43 @@ public class PanelFragmentTest { 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 + ); + } } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java index abefa674623..4dce15edad5 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java +++ b/tests/robotests/src/com/android/settings/panel/PanelSlicesAdapterTest.java @@ -71,7 +71,7 @@ public class PanelSlicesAdapterTest { .getSupportFragmentManager() .findFragmentById(R.id.main_content)); - mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent.getSlices()); + mAdapter = new PanelSlicesAdapter(mPanelFragment, mFakePanelContent); } @Test diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java index 359cf5d7bc3..a51b7b0c7ad 100644 --- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java +++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java @@ -16,13 +16,25 @@ 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.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.runner.RunWith; import org.robolectric.Robolectric; @@ -31,6 +43,22 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) 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 public void startMediaOutputSlice_withPackageName_bundleShouldHaveValue() { final Intent intent = new Intent() @@ -41,7 +69,7 @@ public class SettingsPanelActivityTest { final SettingsPanelActivity activity = 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"); assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT)) .isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT"); @@ -55,7 +83,23 @@ public class SettingsPanelActivityTest { final SettingsPanelActivity activity = 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(); } + + @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 + ); + } }