diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java index 31a3ff4a9b8fa..1544adb231756 100644 --- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java +++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java @@ -65,6 +65,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** * Notification assistant that provides guidance on notification channel blocking @@ -80,6 +82,7 @@ public class Assistant extends NotificationAssistantService { private static final String ATT_KEY = "key"; private static final int DB_VERSION = 1; private static final String ATTR_VERSION = "version"; + private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor(); private static final ArrayList PREJUDICAL_DISMISSALS = new ArrayList<>(); static { @@ -233,15 +236,20 @@ public class Assistant extends NotificationAssistantService { if (!isForCurrentUser(sbn)) { return null; } - NotificationEntry entry = - new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper); - SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry); - if (DEBUG) { - Log.d(TAG, String.format("Creating Adjustment for %s, with %d actions, and %d replies.", - sbn.getKey(), suggestions.actions.size(), suggestions.replies.size())); - } - return createEnqueuedNotificationAdjustment( - entry, suggestions.actions, suggestions.replies); + mSingleThreadExecutor.submit(() -> { + NotificationEntry entry = + new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper); + SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry); + if (DEBUG) { + Log.d(TAG, String.format( + "Creating Adjustment for %s, with %d actions, and %d replies.", + sbn.getKey(), suggestions.actions.size(), suggestions.replies.size())); + } + Adjustment adjustment = createEnqueuedNotificationAdjustment( + entry, suggestions.actions, suggestions.replies); + adjustNotification(adjustment); + }); + return null; } /** A convenience helper for creating an adjustment for an SBN. */ @@ -386,15 +394,15 @@ public class Assistant extends NotificationAssistantService { NotificationEntry entry = mLiveNotifications.get(key); if (entry != null) { - entry.setExpanded(isExpanded); - mSmartActionsHelper.onNotificationExpansionChanged(entry, isUserAction, isExpanded); + mSingleThreadExecutor.submit( + () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded)); } } @Override public void onNotificationDirectReplied(@NonNull String key) { if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key); - mSmartActionsHelper.onNotificationDirectReplied(key); + mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key)); } @Override @@ -404,7 +412,8 @@ public class Assistant extends NotificationAssistantService { Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply + "], source = [" + source + "]"); } - mSmartActionsHelper.onSuggestedReplySent(key, reply, source); + mSingleThreadExecutor.submit( + () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source)); } @Override @@ -415,7 +424,8 @@ public class Assistant extends NotificationAssistantService { "onActionInvoked() called with: key = [" + key + "], action = [" + action.title + "], source = [" + source + "]"); } - mSmartActionsHelper.onActionClicked(key, action, source); + mSingleThreadExecutor.submit( + () -> mSmartActionsHelper.onActionClicked(key, action, source)); } @Override @@ -493,11 +503,6 @@ public class Assistant extends NotificationAssistantService { mPackageManager = pm; } - @VisibleForTesting - public void setSmartActionsHelper(SmartActionsHelper smartActionsHelper) { - mSmartActionsHelper = smartActionsHelper; - } - @VisibleForTesting public ChannelImpressions getImpressions(String key) { synchronized (mkeyToImpressions) { diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java index 546bec21a542b..84a8a8c577f78 100644 --- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java +++ b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java @@ -47,17 +47,18 @@ import java.util.Objects; public class NotificationEntry { static final String TAG = "NotificationEntry"; - private StatusBarNotification mSbn; + private final StatusBarNotification mSbn; private final IPackageManager mPackageManager; private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1; - private boolean mPreChannelsNotification = true; - private AudioAttributes mAttributes; - private NotificationChannel mChannel; - private int mImportance; + private final boolean mPreChannelsNotification; + private final AudioAttributes mAttributes; + private final NotificationChannel mChannel; + private final int mImportance; private boolean mSeen; - private boolean mExpanded; private boolean mIsShowActionEventLogged; - private SmsHelper mSmsHelper; + private final SmsHelper mSmsHelper; + + private final Object mLock = new Object(); public NotificationEntry(IPackageManager packageManager, StatusBarNotification sbn, NotificationChannel channel, SmsHelper smsHelper) { @@ -233,23 +234,27 @@ public class NotificationEntry { } public void setSeen() { - mSeen = true; - } - - public void setExpanded(boolean expanded) { - mExpanded = expanded; + synchronized (mLock) { + mSeen = true; + } } public void setShowActionEventLogged() { - mIsShowActionEventLogged = true; + synchronized (mLock) { + mIsShowActionEventLogged = true; + } } public boolean hasSeen() { - return mSeen; + synchronized (mLock) { + return mSeen; + } } public boolean isShowActionEventLogged() { - return mIsShowActionEventLogged; + synchronized (mLock) { + return mIsShowActionEventLogged; + } } public StatusBarNotification getSbn() { diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java index bf8a3fad1d0fe..0d687d41260d1 100644 --- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java +++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java @@ -53,6 +53,11 @@ import java.util.List; import java.util.Map; import java.util.Objects; +/** + * Generates suggestions from incoming notifications. + * + * Methods in this class should be called in a single worker thread. + */ public class SmartActionsHelper { static final String ENTITIES_EXTRAS = "entities-extras"; static final String KEY_ACTION_TYPE = "action_type"; @@ -287,8 +292,7 @@ public class SmartActionsHelper { return conversationActions; } - void onNotificationExpansionChanged(NotificationEntry entry, boolean isUserAction, - boolean isExpanded) { + void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) { if (!isExpanded) { return; } diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java index 3a7d799ea2ebb..ebcaee87d6d81 100644 --- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java +++ b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java @@ -382,7 +382,7 @@ public class SmartActionsHelperTest { when(mStatusBarNotification.getNotification()).thenReturn(notification); mSmartActionsHelper.suggest(createNotificationEntry()); - mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true, true); + mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(TextClassifierEvent.class); @@ -398,7 +398,7 @@ public class SmartActionsHelperTest { when(mStatusBarNotification.getNotification()).thenReturn(notification); mSmartActionsHelper.suggest(createNotificationEntry()); - mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, false); + mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false); verify(mTextClassifier, never()).onTextClassifierEvent( argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN))); @@ -410,7 +410,7 @@ public class SmartActionsHelperTest { when(mStatusBarNotification.getNotification()).thenReturn(notification); mSmartActionsHelper.suggest(createNotificationEntry()); - mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, true); + mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(TextClassifierEvent.class);