Make sure notifications from the default sms app do not get filtered to the non-interruptive section.

Bug: 123365364
Test: Unit tests and manual testing.
Change-Id: Ide41ff9656ee81aa4fc6f6bcdd00ae886a0e13ee
This commit is contained in:
Nadia Benbernou
2019-01-28 11:26:46 -05:00
parent fb0ce84149
commit 1ee91a3ce8
9 changed files with 166 additions and 20 deletions

View File

@@ -4404,7 +4404,7 @@
{@link android.provider.Telephony.Intents#ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
broadcast -->
<permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
android:protectionLevel="signature" />
android:protectionLevel="signature|privileged" />
<!-- A subclass of {@link android.app.SmsAppService} must be protected with this permission. -->
<permission android:name="android.permission.BIND_SMS_APP_SERVICE"

View File

@@ -22,6 +22,7 @@ applications that come with the platform
<permissions>
<privapp-permissions package="android.ext.services">
<permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
<permission name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
</privapp-permissions>
<privapp-permissions package="com.android.apps.tag">

View File

@@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
<application android:label="@string/app_name"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">

View File

@@ -214,7 +214,8 @@ public class Assistant extends NotificationAssistantService {
if (!isForCurrentUser(sbn)) {
return null;
}
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, sbn, channel, SmsHelper.getInstance(this));
SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
return createEnqueuedNotificationAdjustment(
entry, suggestions.actions, suggestions.replies);
@@ -261,7 +262,7 @@ public class Assistant extends NotificationAssistantService {
Ranking ranking = getRanking(sbn.getKey(), rankingMap);
if (ranking != null && ranking.getChannel() != null) {
NotificationEntry entry = new NotificationEntry(mPackageManager,
sbn, ranking.getChannel());
sbn, ranking.getChannel(), SmsHelper.getInstance(this));
String key = getKey(
sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
@@ -397,6 +398,7 @@ public class Assistant extends NotificationAssistantService {
@Override
public void onListenerConnected() {
if (DEBUG) Log.i(TAG, "CONNECTED");
SmsHelper.getInstance(this).initialize();
try {
mFile = new AtomicFile(new File(new File(
Environment.getDataUserCePackageDirectory(
@@ -413,6 +415,7 @@ public class Assistant extends NotificationAssistantService {
@Override
public void onListenerDisconnected() {
SmsHelper.getInstance(this).destroy();
if (mAgingHelper != null) {
mAgingHelper.onDestroy();
}

View File

@@ -27,6 +27,7 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.Person;
import android.app.RemoteInput;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -56,15 +57,17 @@ public class NotificationEntry {
private boolean mSeen;
private boolean mExpanded;
private boolean mIsShowActionEventLogged;
private SmsHelper mSmsHelper;
public NotificationEntry(IPackageManager packageManager, StatusBarNotification sbn,
NotificationChannel channel) {
NotificationChannel channel, SmsHelper smsHelper) {
mSbn = sbn;
mChannel = channel;
mPackageManager = packageManager;
mPreChannelsNotification = isPreChannelsNotification();
mAttributes = calculateAudioAttributes();
mImportance = calculateInitialImportance();
mSmsHelper = smsHelper;
}
private boolean isPreChannelsNotification() {
@@ -192,7 +195,16 @@ public class NotificationEntry {
protected boolean involvesPeople() {
return isMessaging()
|| hasStyle(Notification.InboxStyle.class)
|| hasPerson();
|| hasPerson()
|| isDefaultSmsApp();
}
private boolean isDefaultSmsApp() {
ComponentName defaultSmsApp = mSmsHelper.getDefaultSmsApplication();
if (defaultSmsApp == null) {
return false;
}
return mSbn.getPackageName().equals(defaultSmsApp.getPackageName());
}
protected boolean isMessaging() {

View File

@@ -0,0 +1,87 @@
/**
* 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 android.ext.services.notification;
import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import com.android.internal.telephony.SmsApplication;
/**
* A helper class for storing and retrieving the default SMS application.
*/
public class SmsHelper {
private static final String TAG = "SmsHelper";
private static SmsHelper sSmsHelper;
private static final Object sLock = new Object();
private final Context mContext;
private ComponentName mDefaultSmsApplication;
private BroadcastReceiver mBroadcastReceiver;
static SmsHelper getInstance(Context context) {
synchronized (sLock) {
if (sSmsHelper == null) {
sSmsHelper = new SmsHelper(context);
}
return sSmsHelper;
}
}
private SmsHelper(Context context) {
mContext = context.getApplicationContext();
}
void initialize() {
if (mBroadcastReceiver == null) {
mDefaultSmsApplication = SmsApplication.getDefaultSmsApplication(mContext, false);
mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
mDefaultSmsApplication =
SmsApplication.getDefaultSmsApplication(mContext, false);
} else {
Log.w(TAG, "Unknown broadcast received: " + intent.getAction());
}
}
};
mContext.registerReceiver(
mBroadcastReceiver,
new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL));
}
}
void destroy() {
if (mBroadcastReceiver != null) {
mContext.unregisterReceiver(mBroadcastReceiver);
mBroadcastReceiver = null;
}
}
@Nullable
public ComponentName getDefaultSmsApplication() {
return mDefaultSmsApplication;
}
}

View File

@@ -67,6 +67,8 @@ public class AgingHelperTest {
private IPackageManager mPackageManager;
@Mock
private AgingHelper.Callback mCallback;
@Mock
private SmsHelper mSmsHelper;
private AgingHelper mAgingHelper;
@@ -99,7 +101,7 @@ public class AgingHelperTest {
public void testNoSnoozingOnPost() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
mAgingHelper.onNotificationPosted(entry);
@@ -110,7 +112,7 @@ public class AgingHelperTest {
public void testPostResetsSnooze() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
mAgingHelper.onNotificationPosted(entry);
@@ -121,7 +123,7 @@ public class AgingHelperTest {
public void testSnoozingOnSeen() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
entry.setSeen();
when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
@@ -134,7 +136,7 @@ public class AgingHelperTest {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = generateSbn(channel.getId());
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
mAgingHelper.onNotificationSeen(entry);

View File

@@ -85,6 +85,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> {
@Mock INotificationManager mNoMan;
@Mock AtomicFile mFile;
@Mock IPackageManager mPackageManager;
@Mock SmsHelper mSmsHelper;
Assistant mAssistant;
Application mApplication;
@@ -467,7 +468,7 @@ public class AssistantTest extends ServiceTestCase<Assistant> {
public void testAssistantNeverIncreasesImportanceWhenSuggestingSilent() throws Exception {
StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "min notif!", null);
Adjustment adjust = mAssistant.createEnqueuedNotificationAdjustment(new NotificationEntry(
mPackageManager, sbn, P1C3), new ArrayList<>(), new ArrayList<>());
mPackageManager, sbn, P1C3, mSmsHelper), new ArrayList<>(), new ArrayList<>());
assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
}
}

View File

@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.Person;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.media.AudioAttributes;
@@ -59,6 +60,10 @@ public class NotificationEntryTest {
private IPackageManager mPackageManager;
@Mock
private ApplicationInfo mAppInfo;
@Mock
private SmsHelper mSmsHelper;
private static final String DEFAULT_SMS_PACKAGE_NAME = "foo";
@Rule
public final TestableContext mContext =
@@ -73,6 +78,15 @@ public class NotificationEntryTest {
UserHandle.SYSTEM, null, 0);
}
private StatusBarNotification generateSbn(String channelId, String packageName) {
Notification n = new Notification.Builder(mContext, channelId)
.setContentTitle("foo")
.build();
return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, n,
UserHandle.SYSTEM, null, 0);
}
private StatusBarNotification generateSbn(Notification n) {
return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
UserHandle.SYSTEM, null, 0);
@@ -86,6 +100,8 @@ public class NotificationEntryTest {
when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
.thenReturn(mAppInfo);
mAppInfo.targetSdkVersion = Build.VERSION_CODES.P;
when(mSmsHelper.getDefaultSmsApplication())
.thenReturn(new ComponentName(DEFAULT_SMS_PACKAGE_NAME, "bar"));
}
@Test
@@ -96,7 +112,7 @@ public class NotificationEntryTest {
people.add(new Person.Builder().setKey("mailto:testing@android.com").build());
sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertTrue(entry.involvesPeople());
}
@@ -104,7 +120,23 @@ public class NotificationEntryTest {
public void testNotPerson() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId());
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertFalse(entry.involvesPeople());
}
@Test
public void testHasPerson_matchesDefaultSmsApp() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME);
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertTrue(entry.involvesPeople());
}
@Test
public void testHasPerson_doesntMatchDefaultSmsApp() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
StatusBarNotification sbn = generateSbn(channel.getId(), "abc");
NotificationEntry entry = new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
assertFalse(entry.involvesPeople());
}
@@ -115,7 +147,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.InboxStyle())
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.hasStyle(Notification.InboxStyle.class));
}
@@ -126,7 +159,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.MessagingStyle(""))
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.hasStyle(Notification.MessagingStyle.class));
}
@@ -137,7 +171,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setStyle(new Notification.BigPictureStyle())
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertFalse(entry.hasStyle(Notification.InboxStyle.class));
assertFalse(entry.hasStyle(Notification.MessagingStyle.class));
}
@@ -148,7 +183,7 @@ public class NotificationEntryTest {
channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build());
NotificationEntry entry = new NotificationEntry(
mPackageManager, generateSbn(channel.getId()), channel);
mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM));
}
@@ -157,7 +192,7 @@ public class NotificationEntryTest {
public void testIsNotAudioAttributes() {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
NotificationEntry entry = new NotificationEntry(
mPackageManager, generateSbn(channel.getId()), channel);
mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM));
}
@@ -169,7 +204,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setCategory(Notification.CATEGORY_EMAIL)
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL));
assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE));
@@ -182,7 +218,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setFlag(FLAG_FOREGROUND_SERVICE, true)
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertTrue(entry.isOngoing());
}
@@ -194,7 +231,8 @@ public class NotificationEntryTest {
Notification n = new Notification.Builder(mContext, channel.getId())
.setFlag(FLAG_CAN_COLORIZE, true)
.build();
NotificationEntry entry = new NotificationEntry(mPackageManager, generateSbn(n), channel);
NotificationEntry entry =
new NotificationEntry(mPackageManager, generateSbn(n), channel, mSmsHelper);
assertFalse(entry.isOngoing());
}