Hide notification channel slice that is interacted

- Ignore interacted package in ContextualNotificationChannelSlice.
- Regularly clear package record with background worker.

Bug:129726858
Test: visual, robotests

Change-Id: I94661a53bcbbe4a15479224c33cfb2eff345aa67
This commit is contained in:
Yanting Yang
2019-04-08 20:30:02 +08:00
parent db7f321526
commit 78e097f239
6 changed files with 290 additions and 3 deletions

View File

@@ -16,30 +16,49 @@
package com.android.settings.homepage.contextualcards.slices;
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.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.util.ArraySet;
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
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 ContextualNotificationChannelSliceTest {
private static final String PACKAGE_NAME = "package_name";
private Context mContext;
private ContextualNotificationChannelSlice mNotificationChannelSlice;
private SharedPreferences mSharedPreferences;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mNotificationChannelSlice = new ContextualNotificationChannelSlice(mContext);
mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE);
}
@After
public void tearDown() {
removeInteractedPackageFromSharedPreference();
}
@Test
@@ -55,4 +74,34 @@ public class ContextualNotificationChannelSliceTest {
assertThat(subTitle).isEqualTo(mContext.getText(R.string.recently_installed_app));
}
@Test
public void isUserInteracted_hasInteractedPackage_shouldBeTrue() {
addInteractedPackageToSharedPreference();
final boolean isInteracted = mNotificationChannelSlice.isUserInteracted(PACKAGE_NAME);
assertThat(isInteracted).isTrue();
}
@Test
public void isUserInteracted_noInteractedPackage_shouldBeFalse() {
final boolean isInteracted = mNotificationChannelSlice.isUserInteracted(PACKAGE_NAME);
assertThat(isInteracted).isFalse();
}
private void addInteractedPackageToSharedPreference() {
final Set<String> interactedPackages = new ArraySet<>();
interactedPackages.add(PACKAGE_NAME);
mSharedPreferences.edit().putStringSet(PREF_KEY_INTERACTED_PACKAGES,
interactedPackages).apply();
}
private void removeInteractedPackageFromSharedPreference() {
if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) {
mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply();
}
}
}

View File

@@ -26,7 +26,6 @@ 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.when;
import static org.robolectric.Shadows.shadowOf;
import android.app.NotificationChannel;
@@ -299,6 +298,21 @@ public class NotificationChannelSliceTest {
assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
}
@Test
@Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public void getSlice_isInteractedPackage_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
false /* isChannelBlocked */);
doReturn(true).when(mNotificationChannelSlice).isUserInteracted(any(String.class));
final Slice slice = mNotificationChannelSlice.getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
}
private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) {
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.name = APP_LABEL;

View File

@@ -0,0 +1,112 @@
/*
* 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.slices;
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.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.util.ArraySet;
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 org.robolectric.shadows.ShadowPackageManager;
import java.util.Set;
@RunWith(RobolectricTestRunner.class)
public class NotificationChannelWorkerTest {
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private static final String PACKAGE_NAME = "com.test.notification.channel.slice";
private Context mContext;
private NotificationChannelWorker mNotificationChannelWorker;
private ShadowPackageManager mPackageManager;
private SharedPreferences mSharedPreferences;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mNotificationChannelWorker = new NotificationChannelWorker(mContext, URI);
// Shadow PackageManager to add mock package.
mPackageManager = shadowOf(mContext.getPackageManager());
mSharedPreferences = mContext.getSharedPreferences(PREFS, MODE_PRIVATE);
addInteractedPackageToSharedPreference();
}
@After
public void tearDown() {
mPackageManager.removePackage(PACKAGE_NAME);
removeInteractedPackageFromSharedPreference();
}
@Test
public void onSliceUnpinned_interactedPackageIsUninstalled_shouldRemovePackage() {
mNotificationChannelWorker.onSliceUnpinned();
final Set<String> interactedPackages = mSharedPreferences.getStringSet(
PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
assertThat(interactedPackages.contains(PACKAGE_NAME)).isFalse();
}
@Test
public void onSliceUnpinned_interactedPackageIsInstalled_shouldKeepPackage() {
mockInteractedPackageAsInstalled();
mNotificationChannelWorker.onSliceUnpinned();
final Set<String> interactedPackages = mSharedPreferences.getStringSet(
PREF_KEY_INTERACTED_PACKAGES, new ArraySet<>());
assertThat(interactedPackages.contains(PACKAGE_NAME)).isTrue();
}
private void mockInteractedPackageAsInstalled() {
final PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = PACKAGE_NAME;
mPackageManager.addPackage(packageInfo);
}
private void addInteractedPackageToSharedPreference() {
final Set<String> interactedPackages = new ArraySet<>();
interactedPackages.add(PACKAGE_NAME);
mSharedPreferences.edit().putStringSet(PREF_KEY_INTERACTED_PACKAGES,
interactedPackages).apply();
}
private void removeInteractedPackageFromSharedPreference() {
if (mSharedPreferences.contains(PREF_KEY_INTERACTED_PACKAGES)) {
mSharedPreferences.edit().remove(PREF_KEY_INTERACTED_PACKAGES).apply();
}
}
}