From b29e53a4504b27b807c726c4099b6a9e69ccdc97 Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Fri, 29 Mar 2019 00:38:56 +0800 Subject: [PATCH] Log interacted package from ContextualNotificationChannelSlice Fixes:129726858 Test: visual, robotests Change-Id: Ife4043fe0bcb52445e8e2efec20781ce43c54fef --- .../ContextualCardFeatureProvider.java | 5 +- .../ContextualCardFeatureProviderImpl.java | 38 +++++ .../slices/SliceFullCardRendererHelper.java | 7 + ...ContextualCardFeatureProviderImplTest.java | 130 ++++++++++++++++++ 4 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java index bba7f533236..bdf863e3385 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java @@ -16,8 +16,11 @@ package com.android.settings.homepage.contextualcards; -import java.util.List; +import androidx.slice.Slice; /** Feature provider for the contextual card feature. */ public interface ContextualCardFeatureProvider { + + /** Log package when user clicks contextual notification channel card. */ + void logNotificationPackage(Slice slice); } diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java index 03a1550cebf..4af2838baa9 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java @@ -16,7 +16,22 @@ package com.android.settings.homepage.contextualcards; +import static android.content.Context.MODE_PRIVATE; + import android.content.Context; +import android.content.SharedPreferences; +import android.util.ArraySet; + +import androidx.slice.Slice; +import androidx.slice.SliceMetadata; +import androidx.slice.core.SliceAction; + +import com.android.settings.SettingsActivity; +import com.android.settings.applications.AppInfoBase; +import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice; +import com.android.settings.slices.CustomSliceRegistry; + +import java.util.Set; public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureProvider { private final Context mContext; @@ -24,4 +39,27 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP public ContextualCardFeatureProviderImpl(Context context) { mContext = context; } + + @Override + public void logNotificationPackage(Slice slice) { + if (slice == null || !slice.getUri().equals( + CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI)) { + return; + } + + final SliceAction primaryAction = SliceMetadata.from(mContext, slice).getPrimaryAction(); + final String currentPackage = primaryAction.getAction().getIntent() + .getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) + .getString(AppInfoBase.ARG_PACKAGE_NAME); + + final SharedPreferences prefs = mContext.getSharedPreferences( + ContextualNotificationChannelSlice.PREFS, MODE_PRIVATE); + final Set interactedPackages = prefs.getStringSet( + ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>()); + + final Set newInteractedPackages = new ArraySet<>(interactedPackages); + newInteractedPackages.add(currentPackage); + prefs.edit().putStringSet(ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES, + newInteractedPackages).apply(); + } } diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java index a9a83466496..f7b2bf5504f 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java @@ -27,6 +27,7 @@ import androidx.slice.widget.SliceView; import com.android.settings.R; import com.android.settings.homepage.contextualcards.ContextualCard; +import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider; import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUtils; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -64,6 +65,12 @@ class SliceFullCardRendererHelper { metricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CONTEXTUAL_CARD_CLICK, log); + + final ContextualCardFeatureProvider contextualCardFeatureProvider = + FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider( + mContext); + + contextualCardFeatureProvider.logNotificationPackage(slice); }); // Customize slice view for Settings diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java new file mode 100644 index 00000000000..e380636774a --- /dev/null +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImplTest.java @@ -0,0 +1,130 @@ +/* + * 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.homepage.contextualcards; + +import static android.content.Context.MODE_PRIVATE; + +import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREFS; +import static com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice.PREF_KEY_INTERACTED_PACKAGES; +import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.FLASHLIGHT_SLICE_URI; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Bundle; +import android.util.ArraySet; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.SliceProvider; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; +import androidx.slice.widget.SliceLiveData; + +import com.android.settings.R; +import com.android.settings.SettingsActivity; +import com.android.settings.applications.AppInfoBase; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.Set; + +@RunWith(RobolectricTestRunner.class) +public class ContextualCardFeatureProviderImplTest { + + private Context mContext; + private ContextualCardFeatureProviderImpl mImpl; + private SharedPreferences mSharedPreferences; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mImpl = new ContextualCardFeatureProviderImpl(mContext); + mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE); + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + } + + @After + public void tearDown() { + removeInteractedPackageFromSharedPreference(); + } + + @Test + public void logNotificationPackage_isContextualNotificationChannel_shouldLogPackage() { + final String packageName = "com.android.test.app"; + final Slice slice = buildSlice(CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI, packageName); + + mImpl.logNotificationPackage(slice); + + final Set interactedPackages = mSharedPreferences.getStringSet( + PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>()); + assertThat(interactedPackages.contains(packageName)).isTrue(); + } + + @Test + public void logNotificationPackage_isNotContextualNotificationChannel_shouldNotLogPackage() { + final String packageName = "com.android.test.app"; + final Slice slice = buildSlice(FLASHLIGHT_SLICE_URI, packageName); + + mImpl.logNotificationPackage(slice); + + final Set interactedPackages = mSharedPreferences.getStringSet( + PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>()); + assertThat(interactedPackages.contains(packageName)).isFalse(); + } + + private Slice buildSlice(Uri sliceUri, String packageName) { + final Bundle args = new Bundle(); + args.putString(AppInfoBase.ARG_PACKAGE_NAME, packageName); + final Intent intent = new Intent("action"); + intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); + + final PendingIntent pendingIntent = spy( + PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */)); + doReturn(intent).when(pendingIntent).getIntent(); + final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.empty_icon); + final SliceAction action = SliceAction.createDeeplink(pendingIntent, icon, + ListBuilder.SMALL_IMAGE, "title"); + + return new ListBuilder(mContext, sliceUri, ListBuilder.INFINITY) + .addRow(new ListBuilder.RowBuilder() + .addEndItem(icon, ListBuilder.ICON_IMAGE) + .setTitle("title") + .setPrimaryAction(action)) + .build(); + } + + private void removeInteractedPackageFromSharedPreference() { + if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) { + mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply(); + } + } +}