Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47d9ba27 authored by Anna Zappone's avatar Anna Zappone Committed by Android (Google) Code Review
Browse files

Merge "Launch app unavailable dialog when WP is off" into sc-dev

parents a59bdc6e 6fac9c78
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -23,18 +23,14 @@ import static com.android.systemui.people.PeopleTileViewHelper.getPersonIconBitm
import static com.android.systemui.people.PeopleTileViewHelper.getSizeInDp;

import android.app.Activity;
import android.app.INotificationManager;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.ServiceManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -43,7 +39,6 @@ import android.widget.LinearLayout;

import com.android.systemui.R;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;

import java.util.ArrayList;
import java.util.List;
@@ -56,19 +51,13 @@ public class PeopleSpaceActivity extends Activity {
    private static final String TAG = "PeopleSpaceActivity";
    private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;

    private IPeopleManager mPeopleManager;
    private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
    private INotificationManager mNotificationManager;
    private LauncherApps mLauncherApps;
    private Context mContext;
    private NotificationEntryManager mNotificationEntryManager;
    private int mAppWidgetId;

    @Inject
    public PeopleSpaceActivity(NotificationEntryManager notificationEntryManager,
            PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
    public PeopleSpaceActivity(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
        super();
        mNotificationEntryManager = notificationEntryManager;
        mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;

    }
@@ -77,11 +66,6 @@ public class PeopleSpaceActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getApplicationContext();
        mNotificationManager = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        mPeopleManager = IPeopleManager.Stub.asInterface(
                ServiceManager.getService(Context.PEOPLE_SERVICE));
        mLauncherApps = mContext.getSystemService(LauncherApps.class);
        mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID,
                INVALID_APPWIDGET_ID);
        setResult(RESULT_CANCELED);
@@ -92,10 +76,8 @@ public class PeopleSpaceActivity extends Activity {
        List<PeopleSpaceTile> priorityTiles = new ArrayList<>();
        List<PeopleSpaceTile> recentTiles = new ArrayList<>();
        try {
            priorityTiles = PeopleSpaceUtils.getPriorityTiles(mContext, mNotificationManager,
                    mPeopleManager, mLauncherApps, mNotificationEntryManager);
            recentTiles = PeopleSpaceUtils.getRecentTiles(mContext, mNotificationManager,
                    mPeopleManager, mLauncherApps, mNotificationEntryManager);
            priorityTiles = mPeopleSpaceWidgetManager.getPriorityTiles();
            recentTiles = mPeopleSpaceWidgetManager.getRecentTiles();
        } catch (Exception e) {
            Log.e(TAG, "Couldn't retrieve conversations", e);
        }
+6 −58
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ package com.android.systemui.people;
import static android.app.Notification.CATEGORY_MISSED_CALL;
import static android.app.Notification.EXTRA_MESSAGES;

import android.annotation.NonNull;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
@@ -41,8 +39,8 @@ import android.os.Bundle;
import android.os.Parcelable;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -119,58 +117,6 @@ public class PeopleSpaceUtils {
        }
    }

    /** Returns a list of map entries corresponding to user's priority conversations. */
    @NonNull
    public static List<PeopleSpaceTile> getPriorityTiles(
            Context context, INotificationManager notificationManager, IPeopleManager peopleManager,
            LauncherApps launcherApps, NotificationEntryManager notificationEntryManager)
            throws Exception {
        List<ConversationChannelWrapper> conversations =
                notificationManager.getConversations(
                        false).getList();
        // Add priority conversations to tiles list.
        Stream<ShortcutInfo> priorityConversations = conversations.stream()
                .filter(c -> c.getNotificationChannel() != null
                        && c.getNotificationChannel().isImportantConversation())
                .map(c -> c.getShortcutInfo());
        List<PeopleSpaceTile> priorityTiles = getSortedTiles(peopleManager, launcherApps,
                priorityConversations);
        priorityTiles = augmentTilesFromVisibleNotifications(
                context, priorityTiles, notificationEntryManager);
        return priorityTiles;
    }

    /** Returns a list of map entries corresponding to user's recent conversations. */
    @NonNull
    public static List<PeopleSpaceTile> getRecentTiles(
            Context context, INotificationManager notificationManager, IPeopleManager peopleManager,
            LauncherApps launcherApps, NotificationEntryManager notificationEntryManager)
            throws Exception {
        if (DEBUG) Log.d(TAG, "Add recent conversations");
        List<ConversationChannelWrapper> conversations =
                notificationManager.getConversations(
                        false).getList();
        Stream<ShortcutInfo> nonPriorityConversations = conversations.stream()
                .filter(c -> c.getNotificationChannel() == null
                        || !c.getNotificationChannel().isImportantConversation())
                .map(c -> c.getShortcutInfo());

        List<ConversationChannel> recentConversationsList =
                peopleManager.getRecentConversations().getList();
        Stream<ShortcutInfo> recentConversations = recentConversationsList
                .stream()
                .map(c -> c.getShortcutInfo());

        Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations,
                recentConversations);
        List<PeopleSpaceTile> recentTiles =
                getSortedTiles(peopleManager, launcherApps, mergedStream);

        recentTiles = augmentTilesFromVisibleNotifications(
                context, recentTiles, notificationEntryManager);
        return recentTiles;
    }

    /** Returns stored widgets for the conversation specified. */
    public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
        if (!key.isValid()) {
@@ -247,7 +193,8 @@ public class PeopleSpaceUtils {
        return augmentedTile.get(0);
    }

    static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
    /** Adds to {@code tiles} any visible notifications. */
    public static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
            List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) {
        if (notificationEntryManager == null) {
            Log.w(TAG, "NotificationEntryManager is null");
@@ -348,11 +295,12 @@ public class PeopleSpaceUtils {
    }

    /** Returns a list sorted by ascending last interaction time from {@code stream}. */
    private static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
            LauncherApps launcherApps,
    public static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
            LauncherApps launcherApps, UserManager userManager,
            Stream<ShortcutInfo> stream) {
        return stream
                .filter(Objects::nonNull)
                .filter(c -> !userManager.isQuietModeEnabled(c.getUserHandle()))
                .map(c -> new PeopleSpaceTile.Builder(c, launcherApps).build())
                .filter(c -> shouldKeepConversation(c))
                .map(c -> c.toBuilder().setLastInteractionTimestamp(
+17 −1
Original line number Diff line number Diff line
@@ -23,11 +23,13 @@ import android.content.pm.LauncherApps;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.NotificationStats;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.statusbar.IStatusBarService;
@@ -48,15 +50,17 @@ public class LaunchConversationActivity extends Activity {
    private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
    private NotificationEntryManager mNotificationEntryManager;
    private final Optional<BubblesManager> mBubblesManagerOptional;
    private final UserManager mUserManager;
    private boolean mIsForTesting;
    private IStatusBarService mIStatusBarService;

    @Inject
    public LaunchConversationActivity(NotificationEntryManager notificationEntryManager,
            Optional<BubblesManager> bubblesManagerOptional) {
            Optional<BubblesManager> bubblesManagerOptional, UserManager userManager) {
        super();
        mNotificationEntryManager = notificationEntryManager;
        mBubblesManagerOptional = bubblesManagerOptional;
        mUserManager = userManager;
    }

    @Override
@@ -80,12 +84,24 @@ public class LaunchConversationActivity extends Activity {
            }
            mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_CLICKED);
            try {

                if (mUserManager.isQuietModeEnabled(userHandle)) {
                    if (DEBUG) Log.d(TAG, "Cannot launch app when quieted");
                    final Intent dialogIntent =
                            UnlaunchableAppActivity.createInQuietModeDialogIntent(
                                    userHandle.getIdentifier());
                    this.getApplicationContext().startActivity(dialogIntent);
                    finish();
                    return;
                }

                NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
                        notificationKey);
                if (entry != null && entry.canBubble() && mBubblesManagerOptional.isPresent()) {
                    if (DEBUG) Log.d(TAG, "Open bubble for conversation");
                    mBubblesManagerOptional.get().expandStackAndSelectBubble(entry);
                    // Just opt-out and don't cancel the notification for bubbles.
                    finish();
                    return;
                }

+63 −2
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds;
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
@@ -51,7 +53,9 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.PreferenceManager;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
@@ -76,6 +80,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;

import javax.inject.Inject;
import javax.inject.Singleton;
@@ -96,6 +101,8 @@ public class PeopleSpaceWidgetManager {
    private NotificationEntryManager mNotificationEntryManager;
    private PackageManager mPackageManager;
    private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
    private INotificationManager mINotificationManager;
    private UserManager mUserManager;
    public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
    @GuardedBy("mLock")
    public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
@@ -121,17 +128,21 @@ public class PeopleSpaceWidgetManager {
        mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
        mPackageManager = mContext.getPackageManager();
        mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider();
        mINotificationManager = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        mUserManager = context.getSystemService(UserManager.class);
    }

    /**
     * AppWidgetManager setter used for testing.
     */
    @VisibleForTesting
    protected void setAppWidgetManager(
    public void setAppWidgetManager(
            AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
            PeopleManager peopleManager, LauncherApps launcherApps,
            NotificationEntryManager notificationEntryManager, PackageManager packageManager,
            boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) {
            boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider,
            UserManager userManager, INotificationManager notificationManager) {
        mAppWidgetManager = appWidgetManager;
        mIPeopleManager = iPeopleManager;
        mPeopleManager = peopleManager;
@@ -140,6 +151,8 @@ public class PeopleSpaceWidgetManager {
        mPackageManager = packageManager;
        mIsForTesting = isForTesting;
        mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider;
        mUserManager = userManager;
        mINotificationManager = notificationManager;
    }

    /**
@@ -783,4 +796,52 @@ public class PeopleSpaceWidgetManager {
        ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class);
        return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback);
    }

    /** Returns a list of map entries corresponding to user's priority conversations. */
    @NonNull
    public List<PeopleSpaceTile> getPriorityTiles()
            throws Exception {
        List<ConversationChannelWrapper> conversations =
                mINotificationManager.getConversations(true).getList();
        // Add priority conversations to tiles list.
        Stream<ShortcutInfo> priorityConversations = conversations.stream()
                .filter(c -> c.getNotificationChannel() != null
                        && c.getNotificationChannel().isImportantConversation())
                .map(c -> c.getShortcutInfo());
        List<PeopleSpaceTile> priorityTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager,
                mLauncherApps, mUserManager,
                priorityConversations);
        priorityTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
                mContext, priorityTiles, mNotificationEntryManager);
        return priorityTiles;
    }

    /** Returns a list of map entries corresponding to user's recent conversations. */
    @NonNull
    public List<PeopleSpaceTile> getRecentTiles()
            throws Exception {
        if (DEBUG) Log.d(TAG, "Add recent conversations");
        List<ConversationChannelWrapper> conversations =
                mINotificationManager.getConversations(false).getList();
        Stream<ShortcutInfo> nonPriorityConversations = conversations.stream()
                .filter(c -> c.getNotificationChannel() == null
                        || !c.getNotificationChannel().isImportantConversation())
                .map(c -> c.getShortcutInfo());

        List<ConversationChannel> recentConversationsList =
                mIPeopleManager.getRecentConversations().getList();
        Stream<ShortcutInfo> recentConversations = recentConversationsList
                .stream()
                .map(c -> c.getShortcutInfo());

        Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations,
                recentConversations);
        List<PeopleSpaceTile> recentTiles =
                PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager,
                        mergedStream);

        recentTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications(
                mContext, recentTiles, mNotificationEntryManager);
        return recentTiles;
    }
}
+0 −115
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@ import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -35,10 +33,7 @@ import static org.mockito.Mockito.when;

import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Person;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
import android.appwidget.AppWidgetManager;
@@ -47,7 +42,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -57,7 +51,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.ContactsContract;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
@@ -81,10 +74,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RunWith(AndroidTestingRunner.class)
@SmallTest
@@ -185,8 +176,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
    @Mock
    private IPeopleManager mPeopleManager;
    @Mock
    private LauncherApps mLauncherApps;
    @Mock
    private IAppWidgetService mIAppWidgetService;
    @Mock
    private AppWidgetManager mAppWidgetManager;
@@ -238,84 +227,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
                .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3));
    }

    @Test
    public void testGetRecentTilesReturnsSortedListWithOnlyRecentConversations() throws Exception {
        // Ensure the less-recent Important conversation is before more recent conversations.
        ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1, false, 3);
        ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1 + 1, true, 3);
        ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1 + 2,
                true, 1);
        when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
                new ParceledListSlice(Arrays.asList(
                        newerNonImportantConversation, newerImportantConversation,
                        olderImportantConversation)));

        // Ensure the non-Important conversation is sorted between these recent conversations.
        ConversationChannel recentConversationBeforeNonImportantConversation =
                getConversationChannel(
                        SHORTCUT_ID_1 + 3, 4);
        ConversationChannel recentConversationAfterNonImportantConversation =
                getConversationChannel(SHORTCUT_ID_1 + 4,
                        2);
        when(mPeopleManager.getRecentConversations()).thenReturn(
                new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
                        recentConversationBeforeNonImportantConversation)));

        List<String> orderedShortcutIds = PeopleSpaceUtils.getRecentTiles(
                mContext, mNotificationManager, mPeopleManager,
                mLauncherApps, mNotificationEntryManager)
                .stream().map(tile -> tile.getId()).collect(Collectors.toList());

        // Check for sorted recent conversations.
        assertThat(orderedShortcutIds).containsExactly(
                recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(),
                newerNonImportantConversation.getShortcutInfo().getId(),
                recentConversationAfterNonImportantConversation.getShortcutInfo().getId())
                .inOrder();
    }

    @Test
    public void testGetPriorityTilesReturnsSortedListWithOnlyImportantConversations()
            throws Exception {
        // Ensure the less-recent Important conversation is before more recent conversations.
        ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1, false, 3);
        ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1 + 1, true, 3);
        ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID_1 + 2,
                true, 1);
        when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
                new ParceledListSlice(Arrays.asList(
                        newerNonImportantConversation, newerImportantConversation,
                        olderImportantConversation)));

        // Ensure the non-Important conversation is sorted between these recent conversations.
        ConversationChannel recentConversationBeforeNonImportantConversation =
                getConversationChannel(
                        SHORTCUT_ID_1 + 3, 4);
        ConversationChannel recentConversationAfterNonImportantConversation =
                getConversationChannel(SHORTCUT_ID_1 + 4,
                        2);
        when(mPeopleManager.getRecentConversations()).thenReturn(
                new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
                        recentConversationBeforeNonImportantConversation)));

        List<String> orderedShortcutIds = PeopleSpaceUtils.getPriorityTiles(
                mContext, mNotificationManager, mPeopleManager,
                mLauncherApps, mNotificationEntryManager)
                .stream().map(tile -> tile.getId()).collect(Collectors.toList());

        // Check for sorted priority conversations.
        assertThat(orderedShortcutIds).containsExactly(
                newerImportantConversation.getShortcutInfo().getId(),
                olderImportantConversation.getShortcutInfo().getId())
                .inOrder();
    }

    @Test
    public void testGetMessagingStyleMessagesNoMessage() {
        Notification notification = new Notification.Builder(mContext, "test")
@@ -570,30 +481,4 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
                any());
    }

    private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
            boolean importantConversation, long lastInteractionTimestamp) throws Exception {
        ConversationChannelWrapper convo = new ConversationChannelWrapper();
        NotificationChannel notificationChannel = new NotificationChannel(shortcutId,
                "channel" + shortcutId,
                NotificationManager.IMPORTANCE_DEFAULT);
        notificationChannel.setImportantConversation(importantConversation);
        convo.setNotificationChannel(notificationChannel);
        convo.setShortcutInfo(new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
                "name").build());
        when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
                eq(shortcutId))).thenReturn(lastInteractionTimestamp);
        return convo;
    }

    private ConversationChannel getConversationChannel(String shortcutId,
            long lastInteractionTimestamp) throws Exception {
        ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
                "name").build();
        ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
                lastInteractionTimestamp, false);
        when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
                eq(shortcutId))).thenReturn(lastInteractionTimestamp);
        return convo;
    }
}
Loading