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:
@@ -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"
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user