Merge "Handle work profile, DND state, app pauses" into sc-dev
This commit is contained in:
@@ -43,6 +43,12 @@ import java.util.List;
|
||||
*/
|
||||
public class PeopleSpaceTile implements Parcelable {
|
||||
|
||||
public static final int SHOW_CONVERSATIONS = 1 << 0;
|
||||
public static final int BLOCK_CONVERSATIONS = 1 << 1;
|
||||
public static final int SHOW_IMPORTANT_CONVERSATIONS = 1 << 2;
|
||||
public static final int SHOW_STARRED_CONTACTS = 1 << 3;
|
||||
public static final int SHOW_CONTACTS = 1 << 4;
|
||||
|
||||
private String mId;
|
||||
private CharSequence mUserName;
|
||||
private Icon mUserIcon;
|
||||
@@ -61,6 +67,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private Intent mIntent;
|
||||
private long mNotificationTimestamp;
|
||||
private List<ConversationStatus> mStatuses;
|
||||
private boolean mCanBypassDnd;
|
||||
private boolean mIsPackageSuspended;
|
||||
private boolean mIsUserQuieted;
|
||||
private int mNotificationPolicyState;
|
||||
private float mContactAffinity;
|
||||
|
||||
private PeopleSpaceTile(Builder b) {
|
||||
mId = b.mId;
|
||||
@@ -81,6 +92,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mIntent = b.mIntent;
|
||||
mNotificationTimestamp = b.mNotificationTimestamp;
|
||||
mStatuses = b.mStatuses;
|
||||
mCanBypassDnd = b.mCanBypassDnd;
|
||||
mIsPackageSuspended = b.mIsPackageSuspended;
|
||||
mIsUserQuieted = b.mIsUserQuieted;
|
||||
mNotificationPolicyState = b.mNotificationPolicyState;
|
||||
mContactAffinity = b.mContactAffinity;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -173,6 +189,41 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return mStatuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the app associated with the conversation can bypass DND.
|
||||
*/
|
||||
public boolean canBypassDnd() {
|
||||
return mCanBypassDnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the app associated with the conversation is suspended.
|
||||
*/
|
||||
public boolean isPackageSuspended() {
|
||||
return mIsPackageSuspended;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user associated with the conversation is quieted.
|
||||
*/
|
||||
public boolean isUserQuieted() {
|
||||
return mIsUserQuieted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of notifications for the conversation.
|
||||
*/
|
||||
public int getNotificationPolicyState() {
|
||||
return mNotificationPolicyState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contact affinity (whether the contact is starred).
|
||||
*/
|
||||
public float getContactAffinity() {
|
||||
return mContactAffinity;
|
||||
}
|
||||
|
||||
/** Converts a {@link PeopleSpaceTile} into a {@link PeopleSpaceTile.Builder}. */
|
||||
public Builder toBuilder() {
|
||||
Builder builder =
|
||||
@@ -192,6 +243,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
builder.setIntent(mIntent);
|
||||
builder.setNotificationTimestamp(mNotificationTimestamp);
|
||||
builder.setStatuses(mStatuses);
|
||||
builder.setCanBypassDnd(mCanBypassDnd);
|
||||
builder.setIsPackageSuspended(mIsPackageSuspended);
|
||||
builder.setIsUserQuieted(mIsUserQuieted);
|
||||
builder.setNotificationPolicyState(mNotificationPolicyState);
|
||||
builder.setContactAffinity(mContactAffinity);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -215,6 +271,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
private Intent mIntent;
|
||||
private long mNotificationTimestamp;
|
||||
private List<ConversationStatus> mStatuses;
|
||||
private boolean mCanBypassDnd;
|
||||
private boolean mIsPackageSuspended;
|
||||
private boolean mIsUserQuieted;
|
||||
private int mNotificationPolicyState;
|
||||
private float mContactAffinity;
|
||||
|
||||
/** Builder for use only if a shortcut is not available for the tile. */
|
||||
public Builder(String id, CharSequence userName, Icon userIcon, Intent intent) {
|
||||
@@ -223,6 +284,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mUserIcon = userIcon;
|
||||
mIntent = intent;
|
||||
mPackageName = intent == null ? null : intent.getPackage();
|
||||
mNotificationPolicyState = SHOW_CONVERSATIONS;
|
||||
}
|
||||
|
||||
public Builder(ShortcutInfo info, LauncherApps launcherApps) {
|
||||
@@ -232,6 +294,7 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mUserHandle = info.getUserHandle();
|
||||
mPackageName = info.getPackage();
|
||||
mContactUri = getContactUri(info);
|
||||
mNotificationPolicyState = SHOW_CONVERSATIONS;
|
||||
}
|
||||
|
||||
public Builder(ConversationChannel channel, LauncherApps launcherApps) {
|
||||
@@ -246,6 +309,9 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mLastInteractionTimestamp = channel.getLastEventTimestamp();
|
||||
mIsImportantConversation = channel.getParentNotificationChannel() != null
|
||||
&& channel.getParentNotificationChannel().isImportantConversation();
|
||||
mCanBypassDnd = channel.getParentNotificationChannel() != null
|
||||
&& channel.getParentNotificationChannel().canBypassDnd();
|
||||
mNotificationPolicyState = SHOW_CONVERSATIONS;
|
||||
}
|
||||
|
||||
/** Returns the Contact's Uri if present. */
|
||||
@@ -366,6 +432,36 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets whether the conversation channel can bypass DND. */
|
||||
public Builder setCanBypassDnd(boolean canBypassDnd) {
|
||||
mCanBypassDnd = canBypassDnd;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets whether the package is suspended. */
|
||||
public Builder setIsPackageSuspended(boolean isPackageSuspended) {
|
||||
mIsPackageSuspended = isPackageSuspended;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets whether the user has been quieted. */
|
||||
public Builder setIsUserQuieted(boolean isUserQuieted) {
|
||||
mIsUserQuieted = isUserQuieted;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the state of blocked notifications for the conversation. */
|
||||
public Builder setNotificationPolicyState(int notificationPolicyState) {
|
||||
mNotificationPolicyState = notificationPolicyState;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the contact's affinity. */
|
||||
public Builder setContactAffinity(float contactAffinity) {
|
||||
mContactAffinity = contactAffinity;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds a {@link PeopleSpaceTile}. */
|
||||
@NonNull
|
||||
public PeopleSpaceTile build() {
|
||||
@@ -393,6 +489,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
mNotificationTimestamp = in.readLong();
|
||||
mStatuses = new ArrayList<>();
|
||||
in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader());
|
||||
mCanBypassDnd = in.readBoolean();
|
||||
mIsPackageSuspended = in.readBoolean();
|
||||
mIsUserQuieted = in.readBoolean();
|
||||
mNotificationPolicyState = in.readInt();
|
||||
mContactAffinity = in.readFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -420,6 +521,11 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
dest.writeParcelable(mIntent, flags);
|
||||
dest.writeLong(mNotificationTimestamp);
|
||||
dest.writeParcelableList(mStatuses, flags);
|
||||
dest.writeBoolean(mCanBypassDnd);
|
||||
dest.writeBoolean(mIsPackageSuspended);
|
||||
dest.writeBoolean(mIsUserQuieted);
|
||||
dest.writeInt(mNotificationPolicyState);
|
||||
dest.writeFloat(mContactAffinity);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull
|
||||
@@ -427,7 +533,6 @@ public class PeopleSpaceTile implements Parcelable {
|
||||
public PeopleSpaceTile createFromParcel(Parcel source) {
|
||||
return new PeopleSpaceTile(source);
|
||||
}
|
||||
|
||||
public PeopleSpaceTile[] newArray(int size) {
|
||||
return new PeopleSpaceTile[size];
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package android.app.people;
|
||||
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
@@ -177,6 +180,71 @@ public class PeopleSpaceTileTest {
|
||||
assertTrue(tile.isImportantConversation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserQuieted() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
|
||||
assertFalse(tile.isUserQuieted());
|
||||
|
||||
tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setIsUserQuieted(true)
|
||||
.build();
|
||||
assertTrue(tile.isUserQuieted());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanBypassDnd() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
|
||||
assertFalse(tile.canBypassDnd());
|
||||
|
||||
tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setCanBypassDnd(true)
|
||||
.build();
|
||||
assertTrue(tile.canBypassDnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationPolicyState() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
|
||||
|
||||
tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
|
||||
.build();
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_IMPORTANT_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageSuspended() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
|
||||
assertFalse(tile.isPackageSuspended());
|
||||
|
||||
tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setIsPackageSuspended(true)
|
||||
.build();
|
||||
assertTrue(tile.isPackageSuspended());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContactAffinity() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
|
||||
assertThat(tile.getContactAffinity()).isEqualTo(0f);
|
||||
|
||||
tile = new PeopleSpaceTile
|
||||
.Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
|
||||
.setContactAffinity(1f)
|
||||
.build();
|
||||
assertThat(tile.getContactAffinity()).isEqualTo(1f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatuses() {
|
||||
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
|
||||
@@ -238,6 +306,11 @@ public class PeopleSpaceTileTest {
|
||||
.setNotificationDataUri(Uri.parse("data"))
|
||||
.setMessagesCount(2)
|
||||
.setIntent(new Intent())
|
||||
.setIsUserQuieted(true)
|
||||
.setCanBypassDnd(false)
|
||||
.setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
|
||||
.setIsPackageSuspended(true)
|
||||
.setContactAffinity(1f)
|
||||
.build();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
@@ -261,6 +334,12 @@ public class PeopleSpaceTileTest {
|
||||
assertThat(readTile.getNotificationDataUri()).isEqualTo(tile.getNotificationDataUri());
|
||||
assertThat(readTile.getMessagesCount()).isEqualTo(tile.getMessagesCount());
|
||||
assertThat(readTile.getIntent().toString()).isEqualTo(tile.getIntent().toString());
|
||||
assertThat(readTile.isUserQuieted()).isEqualTo(tile.isUserQuieted());
|
||||
assertThat(readTile.canBypassDnd()).isEqualTo(tile.canBypassDnd());
|
||||
assertThat(readTile.getNotificationPolicyState()).isEqualTo(
|
||||
tile.getNotificationPolicyState());
|
||||
assertThat(readTile.isPackageSuspended()).isEqualTo(tile.isPackageSuspended());
|
||||
assertThat(readTile.getContactAffinity()).isEqualTo(tile.getContactAffinity());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
29
packages/SystemUI/res/layout/people_tile_empty_layout.xml
Normal file
29
packages/SystemUI/res/layout/people_tile_empty_layout.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
~ Copyright (C) 2021 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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:theme="@android:style/Theme.DeviceDefault.DayNight"
|
||||
android:background="@drawable/people_space_tile_view_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:padding="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</FrameLayout>
|
||||
@@ -26,5 +26,5 @@
|
||||
android:previewLayout="@layout/people_space_placeholder_layout"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:configure="com.android.systemui.people.PeopleSpaceActivity"
|
||||
android:initialLayout="@layout/people_space_initial_layout">
|
||||
android:initialLayout="@layout/people_tile_empty_layout">
|
||||
</appwidget-provider>
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver;
|
||||
|
||||
import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
|
||||
import com.android.systemui.screenshot.ActionProxyReceiver;
|
||||
import com.android.systemui.screenshot.DeleteScreenshotReceiver;
|
||||
import com.android.systemui.screenshot.SmartActionsReceiver;
|
||||
@@ -79,4 +80,13 @@ public abstract class DefaultBroadcastReceiverBinder {
|
||||
public abstract BroadcastReceiver bindPeopleSpaceWidgetPinnedReceiver(
|
||||
PeopleSpaceWidgetPinnedReceiver broadcastReceiver);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(PeopleSpaceWidgetProvider.class)
|
||||
public abstract BroadcastReceiver bindPeopleSpaceWidgetProvider(
|
||||
PeopleSpaceWidgetProvider broadcastReceiver);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.android.systemui.InitController;
|
||||
import com.android.systemui.SystemUIAppComponentFactory;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.keyguard.KeyguardSliceProvider;
|
||||
import com.android.systemui.people.PeopleProvider;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.util.InjectionInflationController;
|
||||
import com.android.wm.shell.ShellCommandHandler;
|
||||
@@ -156,4 +157,9 @@ public interface SysUIComponent {
|
||||
* Member injection into the supplied argument.
|
||||
*/
|
||||
void inject(ClockOptionsProvider clockOptionsProvider);
|
||||
|
||||
/**
|
||||
* Member injection into the supplied argument.
|
||||
*/
|
||||
void inject(PeopleProvider peopleProvider);
|
||||
}
|
||||
|
||||
@@ -30,12 +30,15 @@ import android.widget.RemoteViews;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.shared.system.PeopleProviderUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** API that returns a People Tile preview. */
|
||||
public class PeopleProvider extends ContentProvider {
|
||||
private static final String TAG = "PeopleProvider";
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
@Inject
|
||||
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
|
||||
@Override
|
||||
@@ -76,7 +79,8 @@ public class PeopleProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
if (mPeopleSpaceWidgetManager == null) {
|
||||
mPeopleSpaceWidgetManager = new PeopleSpaceWidgetManager(getContext());
|
||||
Log.e(TAG, "Could not initialize people widget manager");
|
||||
return null;
|
||||
}
|
||||
RemoteViews view =
|
||||
mPeopleSpaceWidgetManager.getPreview(shortcutId, userHandle, packageName, extras);
|
||||
|
||||
@@ -23,11 +23,11 @@ import static com.android.systemui.people.NotificationHelper.hasReadContactsPerm
|
||||
import static com.android.systemui.people.NotificationHelper.isMissedCall;
|
||||
import static com.android.systemui.people.NotificationHelper.shouldMatchNotificationByUri;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
@@ -40,13 +40,11 @@ import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.ContactsContract;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
@@ -56,7 +54,7 @@ import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.AppWidgetOptionsHelper;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
|
||||
@@ -76,45 +74,17 @@ import java.util.stream.Stream;
|
||||
public class PeopleSpaceUtils {
|
||||
/** Turns on debugging information about People Space. */
|
||||
public static final boolean DEBUG = true;
|
||||
private static final String TAG = "PeopleSpaceUtils";
|
||||
public static final String PACKAGE_NAME = "package_name";
|
||||
public static final String USER_ID = "user_id";
|
||||
public static final String SHORTCUT_ID = "shortcut_id";
|
||||
|
||||
public static final String EMPTY_STRING = "";
|
||||
public static final int INVALID_USER_ID = -1;
|
||||
|
||||
public static final PeopleTileKey EMPTY_KEY =
|
||||
new PeopleTileKey(EMPTY_STRING, INVALID_USER_ID, EMPTY_STRING);
|
||||
|
||||
/** Represents whether {@link StatusBarNotification} was posted or removed. */
|
||||
public enum NotificationAction {
|
||||
POSTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/**
|
||||
* The UiEvent enums that this class can log.
|
||||
*/
|
||||
public enum PeopleSpaceWidgetEvent implements UiEventLogger.UiEventEnum {
|
||||
@UiEvent(doc = "People space widget deleted")
|
||||
PEOPLE_SPACE_WIDGET_DELETED(666),
|
||||
@UiEvent(doc = "People space widget added")
|
||||
PEOPLE_SPACE_WIDGET_ADDED(667),
|
||||
@UiEvent(doc = "People space widget clicked to launch conversation")
|
||||
PEOPLE_SPACE_WIDGET_CLICKED(668);
|
||||
|
||||
private final int mId;
|
||||
|
||||
PeopleSpaceWidgetEvent(int id) {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
}
|
||||
static final float STARRED_CONTACT = 1f;
|
||||
static final float VALID_CONTACT = .5f;
|
||||
static final float DEFAULT_AFFINITY = 0f;
|
||||
private static final String TAG = "PeopleSpaceUtils";
|
||||
|
||||
/** Returns stored widgets for the conversation specified. */
|
||||
public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
|
||||
@@ -127,6 +97,10 @@ public class PeopleSpaceUtils {
|
||||
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
|
||||
public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
|
||||
int appWidgetId, Uri contactUri) {
|
||||
if (!key.isValid()) {
|
||||
Log.e(TAG, "Not storing for invalid key");
|
||||
return;
|
||||
}
|
||||
// Write relevant persisted storage.
|
||||
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
@@ -201,7 +175,7 @@ public class PeopleSpaceUtils {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** Returns the total messages in {@code notificationEntries}.*/
|
||||
/** Returns the total messages in {@code notificationEntries}. */
|
||||
public static int getMessagesCount(Set<NotificationEntry> notificationEntries) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Calculating messages count from " + notificationEntries.size()
|
||||
@@ -247,19 +221,34 @@ public class PeopleSpaceUtils {
|
||||
* {@code messagesCount}.
|
||||
*/
|
||||
public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
|
||||
PeopleTileKey key, NotificationEntry notificationEntry, int messagesCount) {
|
||||
PeopleTileKey key, NotificationEntry notificationEntry, int messagesCount,
|
||||
Optional<Integer> appWidgetId) {
|
||||
if (notificationEntry == null || notificationEntry.getSbn().getNotification() == null) {
|
||||
if (DEBUG) Log.d(TAG, "Tile key: " + key.toString() + ". Notification is null");
|
||||
return removeNotificationFields(tile);
|
||||
}
|
||||
Notification notification = notificationEntry.getSbn().getNotification();
|
||||
|
||||
PeopleSpaceTile.Builder updatedTile = tile.toBuilder();
|
||||
String uriFromNotification = getContactUri(notificationEntry.getSbn());
|
||||
if (appWidgetId.isPresent() && tile.getContactUri() == null && !TextUtils.isEmpty(
|
||||
uriFromNotification)) {
|
||||
if (DEBUG) Log.d(TAG, "Add uri from notification to tile: " + uriFromNotification);
|
||||
Uri contactUri = Uri.parse(uriFromNotification);
|
||||
// Update storage.
|
||||
setSharedPreferencesStorageForTile(context, new PeopleTileKey(tile), appWidgetId.get(),
|
||||
contactUri);
|
||||
// Update cached tile in-memory.
|
||||
updatedTile.setContactUri(contactUri);
|
||||
}
|
||||
|
||||
boolean isMissedCall = isMissedCall(notification);
|
||||
List<Notification.MessagingStyle.Message> messages =
|
||||
getMessagingStyleMessages(notification);
|
||||
|
||||
if (!isMissedCall && ArrayUtils.isEmpty(messages)) {
|
||||
if (DEBUG) Log.d(TAG, "Tile key: " + key.toString() + ". Notification has no content");
|
||||
return removeNotificationFields(tile);
|
||||
return removeNotificationFields(updatedTile.build());
|
||||
}
|
||||
|
||||
// messages are in chronological order from most recent to least.
|
||||
@@ -276,8 +265,7 @@ public class PeopleSpaceUtils {
|
||||
}
|
||||
CharSequence sender = getSenderIfGroupConversation(notification, message);
|
||||
|
||||
return tile
|
||||
.toBuilder()
|
||||
return updatedTile
|
||||
.setNotificationKey(notificationEntry.getSbn().getKey())
|
||||
.setNotificationCategory(notification.category)
|
||||
.setNotificationContent(content)
|
||||
@@ -378,17 +366,18 @@ public class PeopleSpaceUtils {
|
||||
context.getString(R.string.birthday_status));
|
||||
}
|
||||
|
||||
/** Calls to retrieve birthdays on a background thread. */
|
||||
public static void getBirthdaysOnBackgroundThread(Context context,
|
||||
AppWidgetManager appWidgetManager,
|
||||
/** Calls to retrieve birthdays & contact affinity on a background thread. */
|
||||
public static void getDataFromContactsOnBackgroundThread(Context context,
|
||||
PeopleSpaceWidgetManager manager,
|
||||
Map<Integer, PeopleSpaceTile> peopleSpaceTiles, int[] appWidgetIds) {
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> getBirthdays(context, appWidgetManager, peopleSpaceTiles, appWidgetIds));
|
||||
() -> getDataFromContacts(context, manager, peopleSpaceTiles, appWidgetIds));
|
||||
}
|
||||
|
||||
/** Queries the Contacts DB for any birthdays today. */
|
||||
/** Queries the Contacts DB for any birthdays today & updates contact affinity. */
|
||||
@VisibleForTesting
|
||||
public static void getBirthdays(Context context, AppWidgetManager appWidgetManager,
|
||||
public static void getDataFromContacts(Context context,
|
||||
PeopleSpaceWidgetManager peopleSpaceWidgetManager,
|
||||
Map<Integer, PeopleSpaceTile> widgetIdToTile, int[] appWidgetIds) {
|
||||
if (DEBUG) Log.d(TAG, "Get birthdays");
|
||||
if (appWidgetIds.length == 0) return;
|
||||
@@ -397,28 +386,37 @@ public class PeopleSpaceUtils {
|
||||
PeopleSpaceTile storedTile = widgetIdToTile.get(appWidgetId);
|
||||
if (storedTile == null || storedTile.getContactUri() == null) {
|
||||
if (DEBUG) Log.d(TAG, "No contact uri for: " + storedTile);
|
||||
removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
|
||||
updateTileContactFields(peopleSpaceWidgetManager, context, storedTile,
|
||||
appWidgetId, DEFAULT_AFFINITY, /* birthdayString= */ null);
|
||||
continue;
|
||||
}
|
||||
if (lookupKeysWithBirthdaysToday.isEmpty()) {
|
||||
if (DEBUG) Log.d(TAG, "No birthdays today");
|
||||
removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
|
||||
continue;
|
||||
}
|
||||
updateTileWithBirthday(context, appWidgetManager, lookupKeysWithBirthdaysToday,
|
||||
updateTileWithBirthdayAndUpdateAffinity(context, peopleSpaceWidgetManager,
|
||||
lookupKeysWithBirthdaysToday,
|
||||
storedTile,
|
||||
appWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the birthday status if present in {@code storedTile} and pushes the update. */
|
||||
private static void removeBirthdayStatusIfPresent(AppWidgetManager appWidgetManager,
|
||||
Context context, PeopleSpaceTile storedTile, int appWidgetId) {
|
||||
if (hasBirthdayStatus(storedTile, context)) {
|
||||
if (DEBUG) Log.d(TAG, "Remove " + storedTile.getUserName() + "'s birthday");
|
||||
updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId,
|
||||
/**
|
||||
* Updates the {@code storedTile} with {@code affinity} & {@code birthdayString} if
|
||||
* necessary.
|
||||
*/
|
||||
private static void updateTileContactFields(PeopleSpaceWidgetManager manager,
|
||||
Context context, PeopleSpaceTile storedTile, int appWidgetId, float affinity,
|
||||
@Nullable String birthdayString) {
|
||||
boolean outdatedBirthdayStatus = hasBirthdayStatus(storedTile, context)
|
||||
&& birthdayString == null;
|
||||
boolean addBirthdayStatus = !hasBirthdayStatus(storedTile, context)
|
||||
&& birthdayString != null;
|
||||
boolean shouldUpdate =
|
||||
storedTile.getContactAffinity() != affinity || outdatedBirthdayStatus
|
||||
|| addBirthdayStatus;
|
||||
if (shouldUpdate) {
|
||||
if (DEBUG) Log.d(TAG, "Update " + storedTile.getUserName() + " from contacts");
|
||||
manager.updateAppWidgetOptionsAndView(appWidgetId,
|
||||
storedTile.toBuilder()
|
||||
.setBirthdayText(null)
|
||||
.setBirthdayText(birthdayString)
|
||||
.setContactAffinity(affinity)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@@ -427,7 +425,8 @@ public class PeopleSpaceUtils {
|
||||
* Update {@code storedTile} if the contact has a lookup key matched to any {@code
|
||||
* lookupKeysWithBirthdays}.
|
||||
*/
|
||||
private static void updateTileWithBirthday(Context context, AppWidgetManager appWidgetManager,
|
||||
private static void updateTileWithBirthdayAndUpdateAffinity(Context context,
|
||||
PeopleSpaceWidgetManager manager,
|
||||
List<String> lookupKeysWithBirthdaysToday, PeopleSpaceTile storedTile,
|
||||
int appWidgetId) {
|
||||
Cursor cursor = null;
|
||||
@@ -437,14 +436,16 @@ public class PeopleSpaceUtils {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String storedLookupKey = cursor.getString(
|
||||
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.LOOKUP_KEY));
|
||||
float affinity = getContactAffinity(cursor);
|
||||
if (!storedLookupKey.isEmpty() && lookupKeysWithBirthdaysToday.contains(
|
||||
storedLookupKey)) {
|
||||
if (DEBUG) Log.d(TAG, storedTile.getUserName() + "'s birthday today!");
|
||||
updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId,
|
||||
storedTile.toBuilder()
|
||||
.setBirthdayText(context.getString(R.string.birthday_status))
|
||||
.build());
|
||||
return;
|
||||
updateTileContactFields(manager, context, storedTile, appWidgetId,
|
||||
affinity, /* birthdayString= */
|
||||
context.getString(R.string.birthday_status));
|
||||
} else {
|
||||
updateTileContactFields(manager, context, storedTile, appWidgetId,
|
||||
affinity, /* birthdayString= */ null);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
@@ -454,51 +455,20 @@ public class PeopleSpaceUtils {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
|
||||
}
|
||||
|
||||
/** Updates the current widget view with provided {@link PeopleSpaceTile}. */
|
||||
public static void updateAppWidgetViews(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, PeopleSpaceTile tile, Bundle options) {
|
||||
if (tile == null) {
|
||||
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ". Tile is null, skipping update");
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName() + ", "
|
||||
+ tile.getPackageName() + ". Updating app widget view.");
|
||||
}
|
||||
RemoteViews views = new PeopleTileViewHelper(context, tile, appWidgetId,
|
||||
options).getViews();
|
||||
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget.
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
|
||||
/** Updates tile in app widget options and the current view. */
|
||||
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, PeopleSpaceTile tile) {
|
||||
if (tile == null) {
|
||||
if (DEBUG) {
|
||||
Log.w(TAG, "Widget: " + appWidgetId + "Tile is null, skipping storage and update.");
|
||||
/** Pulls the contact affinity from {@code cursor}. */
|
||||
private static float getContactAffinity(Cursor cursor) {
|
||||
float affinity = VALID_CONTACT;
|
||||
int starIdx = cursor.getColumnIndex(ContactsContract.Contacts.STARRED);
|
||||
if (starIdx >= 0) {
|
||||
boolean isStarred = cursor.getInt(starIdx) != 0;
|
||||
if (isStarred) {
|
||||
affinity = Math.max(affinity, STARRED_CONTACT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Bundle options = AppWidgetOptionsHelper.setPeopleTile(appWidgetManager, appWidgetId, tile);
|
||||
updateAppWidgetViews(appWidgetManager, context, appWidgetId, tile, options);
|
||||
}
|
||||
|
||||
/** Wrapper around {@link #updateAppWidgetOptionsAndView} with optional tile as a parameter. */
|
||||
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, Optional<PeopleSpaceTile> optionalTile) {
|
||||
if (!optionalTile.isPresent()) {
|
||||
if (DEBUG) {
|
||||
Log.w(TAG, "Widget: " + appWidgetId
|
||||
+ "Optional tile is not present, skipping storage and update.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, optionalTile.get());
|
||||
if (DEBUG) Log.d(TAG, "Affinity is: " + affinity);
|
||||
return affinity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,4 +516,33 @@ public class PeopleSpaceUtils {
|
||||
public static int getUserId(PeopleSpaceTile tile) {
|
||||
return tile.getUserHandle().getIdentifier();
|
||||
}
|
||||
|
||||
/** Represents whether {@link StatusBarNotification} was posted or removed. */
|
||||
public enum NotificationAction {
|
||||
POSTED,
|
||||
REMOVED
|
||||
}
|
||||
|
||||
/**
|
||||
* The UiEvent enums that this class can log.
|
||||
*/
|
||||
public enum PeopleSpaceWidgetEvent implements UiEventLogger.UiEventEnum {
|
||||
@UiEvent(doc = "People space widget deleted")
|
||||
PEOPLE_SPACE_WIDGET_DELETED(666),
|
||||
@UiEvent(doc = "People space widget added")
|
||||
PEOPLE_SPACE_WIDGET_ADDED(667),
|
||||
@UiEvent(doc = "People space widget clicked to launch conversation")
|
||||
PEOPLE_SPACE_WIDGET_CLICKED(668);
|
||||
|
||||
private final int mId;
|
||||
|
||||
PeopleSpaceWidgetEvent(int id) {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
|
||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
|
||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
|
||||
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
|
||||
|
||||
@@ -39,6 +41,8 @@ import android.app.people.ConversationStatus;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -48,6 +52,7 @@ import android.icu.util.Measure;
|
||||
import android.icu.util.MeasureUnit;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
@@ -57,6 +62,8 @@ import android.widget.RemoteViews;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.LaunchConversationActivity;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
|
||||
@@ -142,7 +149,9 @@ public class PeopleTileViewHelper {
|
||||
private int mMediumVerticalPadding;
|
||||
|
||||
private Context mContext;
|
||||
@Nullable
|
||||
private PeopleSpaceTile mTile;
|
||||
private PeopleTileKey mKey;
|
||||
private float mDensity;
|
||||
private int mAppWidgetId;
|
||||
private int mWidth;
|
||||
@@ -152,10 +161,11 @@ public class PeopleTileViewHelper {
|
||||
private Locale mLocale;
|
||||
private NumberFormat mIntegerFormat;
|
||||
|
||||
public PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
|
||||
int appWidgetId, Bundle options) {
|
||||
public PeopleTileViewHelper(Context context, @Nullable PeopleSpaceTile tile,
|
||||
int appWidgetId, Bundle options, PeopleTileKey key) {
|
||||
mContext = context;
|
||||
mTile = tile;
|
||||
mKey = key;
|
||||
mAppWidgetId = appWidgetId;
|
||||
mDensity = mContext.getResources().getDisplayMetrics().density;
|
||||
int display = mContext.getResources().getConfiguration().orientation;
|
||||
@@ -184,8 +194,19 @@ public class PeopleTileViewHelper {
|
||||
* content, then birthdays, then the most recent status, and finally last interaction.
|
||||
*/
|
||||
private RemoteViews getViewForTile() {
|
||||
PeopleTileKey key = new PeopleTileKey(mTile);
|
||||
if (DEBUG) Log.d(TAG, "Creating view for tile key: " + key.toString());
|
||||
if (DEBUG) Log.d(TAG, "Creating view for tile key: " + mKey.toString());
|
||||
if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted()) {
|
||||
if (DEBUG) Log.d(TAG, "Create empty view: " + mTile);
|
||||
return createEmptyView();
|
||||
}
|
||||
|
||||
boolean dndBlockingTileData = isDndBlockingTileData(mTile);
|
||||
if (dndBlockingTileData) {
|
||||
if (DEBUG) Log.d(TAG, "Create DND view: " + mTile.getNotificationPolicyState());
|
||||
// TODO: Create DND view.
|
||||
return createEmptyView();
|
||||
}
|
||||
|
||||
if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
|
||||
if (DEBUG) Log.d(TAG, "Create missed call view");
|
||||
return createMissedCallRemoteViews();
|
||||
@@ -217,6 +238,58 @@ public class PeopleTileViewHelper {
|
||||
return createLastInteractionRemoteViews();
|
||||
}
|
||||
|
||||
private boolean isDndBlockingTileData(PeopleSpaceTile tile) {
|
||||
int notificationPolicyState = tile.getNotificationPolicyState();
|
||||
if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONVERSATIONS) != 0) {
|
||||
// Not in DND, or all conversations
|
||||
if (DEBUG) Log.d(TAG, "Tile can show all data: " + tile.getUserName());
|
||||
return false;
|
||||
}
|
||||
if ((notificationPolicyState & PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS) != 0
|
||||
&& tile.isImportantConversation()) {
|
||||
if (DEBUG) Log.d(TAG, "Tile can show important: " + tile.getUserName());
|
||||
return false;
|
||||
}
|
||||
if ((notificationPolicyState & PeopleSpaceTile.SHOW_STARRED_CONTACTS) != 0
|
||||
&& tile.getContactAffinity() == STARRED_CONTACT) {
|
||||
if (DEBUG) Log.d(TAG, "Tile can show starred: " + tile.getUserName());
|
||||
return false;
|
||||
}
|
||||
if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONTACTS) != 0
|
||||
&& (tile.getContactAffinity() == VALID_CONTACT
|
||||
|| tile.getContactAffinity() == STARRED_CONTACT)) {
|
||||
if (DEBUG) Log.d(TAG, "Tile can show contacts: " + tile.getUserName());
|
||||
return false;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Tile can show if can bypass DND: " + tile.getUserName());
|
||||
return !tile.canBypassDnd();
|
||||
}
|
||||
|
||||
private RemoteViews createEmptyView() {
|
||||
RemoteViews views = new RemoteViews(mContext.getPackageName(),
|
||||
R.layout.people_tile_empty_layout);
|
||||
Drawable appIcon = getAppBadge(mKey.getPackageName(), mKey.getUserId());
|
||||
Bitmap appIconAsBitmap = convertDrawableToBitmap(appIcon);
|
||||
FastBitmapDrawable drawable = new FastBitmapDrawable(
|
||||
appIconAsBitmap);
|
||||
drawable.setIsDisabled(true);
|
||||
Bitmap convertedBitmap = convertDrawableToBitmap(drawable);
|
||||
views.setImageViewBitmap(R.id.item, convertedBitmap);
|
||||
return views;
|
||||
}
|
||||
|
||||
private Drawable getAppBadge(String packageName, int userId) {
|
||||
Drawable badge = null;
|
||||
try {
|
||||
final ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfoAsUser(
|
||||
packageName, PackageManager.GET_META_DATA, userId);
|
||||
badge = Utils.getBadgedIcon(mContext, appInfo);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
badge = mContext.getPackageManager().getDefaultActivityIcon();
|
||||
}
|
||||
return badge;
|
||||
}
|
||||
|
||||
private void setMaxLines(RemoteViews views, boolean showSender) {
|
||||
int textSize = mLayoutSize == LAYOUT_LARGE ? getSizeInDp(
|
||||
R.dimen.content_text_size_for_medium)
|
||||
@@ -337,6 +410,9 @@ public class PeopleTileViewHelper {
|
||||
private RemoteViews setCommonRemoteViewsFields(RemoteViews views,
|
||||
int maxAvatarSize) {
|
||||
try {
|
||||
if (mTile == null) {
|
||||
return views;
|
||||
}
|
||||
boolean isAvailable =
|
||||
mTile.getStatuses() != null && mTile.getStatuses().stream().anyMatch(
|
||||
c -> c.getAvailability() == AVAILABILITY_AVAILABLE);
|
||||
@@ -367,13 +443,16 @@ public class PeopleTileViewHelper {
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, mTile.getId());
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, mKey.getShortcutId());
|
||||
activityIntent.putExtra(
|
||||
PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, mTile.getPackageName());
|
||||
PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, mKey.getPackageName());
|
||||
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE,
|
||||
mTile.getUserHandle());
|
||||
activityIntent.putExtra(
|
||||
PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, mTile.getNotificationKey());
|
||||
new UserHandle(mKey.getUserId()));
|
||||
if (mTile != null) {
|
||||
activityIntent.putExtra(
|
||||
PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY,
|
||||
mTile.getNotificationKey());
|
||||
}
|
||||
views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
|
||||
mContext,
|
||||
mAppWidgetId,
|
||||
@@ -727,6 +806,9 @@ public class PeopleTileViewHelper {
|
||||
c -> c.getActivity() == ACTIVITY_NEW_STORY);
|
||||
|
||||
Icon icon = tile.getUserIcon();
|
||||
if (icon == null) {
|
||||
return null;
|
||||
}
|
||||
PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(context,
|
||||
context.getPackageManager(),
|
||||
IconDrawableFactory.newInstance(context, false),
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
package com.android.systemui.people.widget;
|
||||
|
||||
import static android.Manifest.permission.READ_CONTACTS;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
|
||||
import static android.content.Intent.ACTION_BOOT_COMPLETED;
|
||||
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
|
||||
|
||||
import static com.android.systemui.people.NotificationHelper.getContactUri;
|
||||
import static com.android.systemui.people.NotificationHelper.getHighestPriorityNotification;
|
||||
@@ -30,13 +36,12 @@ import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotifi
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getMessagesCount;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getNotificationsByUri;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.removeNotificationFields;
|
||||
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.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Person;
|
||||
import android.app.people.ConversationChannel;
|
||||
@@ -44,8 +49,11 @@ import android.app.people.IPeopleManager;
|
||||
import android.app.people.PeopleManager;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -60,6 +68,8 @@ import android.preference.PreferenceManager;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
@@ -67,8 +77,9 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.people.NotificationHelper;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
import com.android.systemui.people.PeopleTileViewHelper;
|
||||
@@ -85,15 +96,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/** Manager for People Space widget. */
|
||||
@Singleton
|
||||
@SysUISingleton
|
||||
public class PeopleSpaceWidgetManager {
|
||||
private static final String TAG = "PeopleSpaceWidgetMgr";
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
@@ -107,12 +118,15 @@ public class PeopleSpaceWidgetManager {
|
||||
private PeopleManager mPeopleManager;
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
private PackageManager mPackageManager;
|
||||
private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
|
||||
private INotificationManager mINotificationManager;
|
||||
private UserManager mUserManager;
|
||||
private PeopleSpaceWidgetManager mManager;
|
||||
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
private NotificationManager mNotificationManager;
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
private Executor mBgExecutor;
|
||||
@GuardedBy("mLock")
|
||||
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
|
||||
public static Map<PeopleTileKey, TileConversationListener>
|
||||
mListeners = new HashMap<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -120,46 +134,91 @@ public class PeopleSpaceWidgetManager {
|
||||
// This is required because on notification removal, the contact Uri field is stripped and we
|
||||
// only have the notification key to determine which widget IDs should be updated.
|
||||
private Map<String, Set<String>> mNotificationKeyToWidgetIdsMatchedByUri = new HashMap<>();
|
||||
private boolean mIsForTesting;
|
||||
private boolean mRegisteredReceivers;
|
||||
|
||||
@Inject
|
||||
public PeopleSpaceWidgetManager(Context context) {
|
||||
public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps,
|
||||
NotificationEntryManager notificationEntryManager,
|
||||
PackageManager packageManager, UserManager userManager,
|
||||
NotificationManager notificationManager, BroadcastDispatcher broadcastDispatcher,
|
||||
@Background Executor bgExecutor) {
|
||||
if (DEBUG) Log.d(TAG, "constructor");
|
||||
mContext = context;
|
||||
mAppWidgetManager = AppWidgetManager.getInstance(context);
|
||||
mIPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
mLauncherApps = context.getSystemService(LauncherApps.class);
|
||||
mLauncherApps = launcherApps;
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
mPeopleManager = mContext.getSystemService(PeopleManager.class);
|
||||
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider();
|
||||
mPeopleManager = context.getSystemService(PeopleManager.class);
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
mPackageManager = packageManager;
|
||||
mINotificationManager = INotificationManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
mUserManager = userManager;
|
||||
mNotificationManager = notificationManager;
|
||||
mManager = this;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mBgExecutor = bgExecutor;
|
||||
}
|
||||
|
||||
/** Initializes {@PeopleSpaceWidgetManager}. */
|
||||
public void init() {
|
||||
synchronized (mLock) {
|
||||
if (!mRegisteredReceivers) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
filter.addAction(ACTION_BOOT_COMPLETED);
|
||||
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
|
||||
filter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
|
||||
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
|
||||
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
|
||||
filter.addAction(Intent.ACTION_USER_UNLOCKED);
|
||||
mBroadcastDispatcher.registerReceiver(mBaseBroadcastReceiver, filter,
|
||||
null /* executor */, UserHandle.ALL);
|
||||
mRegisteredReceivers = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Listener for the shortcut data changes. */
|
||||
public class TileConversationListener implements PeopleManager.ConversationListener {
|
||||
|
||||
@Override
|
||||
public void onConversationUpdate(@NonNull ConversationChannel conversation) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"Received updated conversation: "
|
||||
+ conversation.getShortcutInfo().getLabel());
|
||||
}
|
||||
updateWidgetsWithConversationChanged(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AppWidgetManager setter used for testing.
|
||||
* PeopleSpaceWidgetManager setter used for testing.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void setAppWidgetManager(
|
||||
PeopleSpaceWidgetManager(Context context,
|
||||
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
|
||||
PeopleManager peopleManager, LauncherApps launcherApps,
|
||||
NotificationEntryManager notificationEntryManager, PackageManager packageManager,
|
||||
boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider,
|
||||
UserManager userManager, INotificationManager notificationManager) {
|
||||
UserManager userManager, INotificationManager iNotificationManager,
|
||||
NotificationManager notificationManager, @Background Executor executor) {
|
||||
mContext = context;
|
||||
mAppWidgetManager = appWidgetManager;
|
||||
mIPeopleManager = iPeopleManager;
|
||||
mPeopleManager = peopleManager;
|
||||
mLauncherApps = launcherApps;
|
||||
mNotificationEntryManager = notificationEntryManager;
|
||||
mPackageManager = packageManager;
|
||||
mIsForTesting = isForTesting;
|
||||
mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider;
|
||||
mUserManager = userManager;
|
||||
mINotificationManager = notificationManager;
|
||||
mINotificationManager = iNotificationManager;
|
||||
mNotificationManager = notificationManager;
|
||||
mManager = this;
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
mBgExecutor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,7 +232,7 @@ public class PeopleSpaceWidgetManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets");
|
||||
if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets: " + widgetIds);
|
||||
synchronized (mLock) {
|
||||
updateSingleConversationWidgets(widgetIds);
|
||||
}
|
||||
@@ -191,16 +250,47 @@ public class PeopleSpaceWidgetManager {
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
|
||||
if (tile == null) {
|
||||
if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
|
||||
//TODO: Delete app widget id when crash is fixed (b/172932636)
|
||||
continue;
|
||||
Log.e(TAG, "Matching conversation not found for shortcut ID");
|
||||
}
|
||||
Bundle options = mAppWidgetManager.getAppWidgetOptions(appWidgetId);
|
||||
updateAppWidgetViews(mAppWidgetManager, mContext, appWidgetId, tile, options);
|
||||
updateAppWidgetViews(appWidgetId, tile, options);
|
||||
widgetIdToTile.put(appWidgetId, tile);
|
||||
if (tile != null) {
|
||||
registerConversationListenerIfNeeded(appWidgetId,
|
||||
new PeopleTileKey(tile));
|
||||
}
|
||||
}
|
||||
PeopleSpaceUtils.getBirthdaysOnBackgroundThread(
|
||||
mContext, mAppWidgetManager, widgetIdToTile, appWidgetIds);
|
||||
PeopleSpaceUtils.getDataFromContactsOnBackgroundThread(
|
||||
mContext, mManager, widgetIdToTile, appWidgetIds);
|
||||
}
|
||||
|
||||
/** Updates the current widget view with provided {@link PeopleSpaceTile}. */
|
||||
private void updateAppWidgetViews(int appWidgetId, PeopleSpaceTile tile, Bundle options) {
|
||||
PeopleTileKey key = getKeyFromStorageByWidgetId(appWidgetId);
|
||||
if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());
|
||||
if (!key.isValid()) {
|
||||
Log.e(TAG, "Cannot update invalid widget");
|
||||
return;
|
||||
}
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext, tile, appWidgetId,
|
||||
options, key).getViews();
|
||||
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget.
|
||||
mAppWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
|
||||
/** Updates tile in app widget options and the current view. */
|
||||
public void updateAppWidgetOptionsAndViewOptional(int appWidgetId,
|
||||
Optional<PeopleSpaceTile> tile) {
|
||||
if (tile.isPresent()) {
|
||||
updateAppWidgetOptionsAndView(appWidgetId, tile.get());
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates tile in app widget options and the current view. */
|
||||
public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
|
||||
Bundle options = AppWidgetOptionsHelper.setPeopleTile(mAppWidgetManager, appWidgetId, tile);
|
||||
updateAppWidgetViews(appWidgetId, tile, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +316,7 @@ public class PeopleSpaceWidgetManager {
|
||||
widgetSp.getInt(USER_ID, INVALID_USER_ID),
|
||||
widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
|
||||
|
||||
return getTileFromPersistentStorage(key);
|
||||
return getTileFromPersistentStorage(key, appWidgetId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,7 +324,7 @@ public class PeopleSpaceWidgetManager {
|
||||
* If a {@link PeopleTileKey} is not provided, fetch one from {@link SharedPreferences}.
|
||||
*/
|
||||
@Nullable
|
||||
public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key) {
|
||||
public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId) {
|
||||
if (!key.isValid()) {
|
||||
Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
|
||||
return null;
|
||||
@@ -254,7 +344,22 @@ public class PeopleSpaceWidgetManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PeopleSpaceTile.Builder(channel, mLauncherApps).build();
|
||||
// Get tile from shortcut & conversation storage.
|
||||
PeopleSpaceTile.Builder storedTile = new PeopleSpaceTile.Builder(channel,
|
||||
mLauncherApps);
|
||||
if (storedTile == null) {
|
||||
return storedTile.build();
|
||||
}
|
||||
|
||||
// Supplement with our storage.
|
||||
String contactUri = mSharedPrefs.getString(String.valueOf(appWidgetId), null);
|
||||
if (contactUri != null && storedTile.build().getContactUri() == null) {
|
||||
if (DEBUG) Log.d(TAG, "Restore contact uri from storage: " + contactUri);
|
||||
storedTile.setContactUri(Uri.parse(contactUri));
|
||||
}
|
||||
|
||||
// Add current state.
|
||||
return updateWithCurrentState(storedTile.build(), ACTION_BOOT_COMPLETED);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to retrieve conversation for tile: " + e);
|
||||
return null;
|
||||
@@ -275,11 +380,7 @@ public class PeopleSpaceWidgetManager {
|
||||
Log.d(TAG, "Notification removed, key: " + sbn.getKey());
|
||||
}
|
||||
}
|
||||
if (mIsForTesting) {
|
||||
updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction);
|
||||
return;
|
||||
}
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
mBgExecutor.execute(
|
||||
() -> updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction));
|
||||
}
|
||||
|
||||
@@ -331,8 +432,7 @@ public class PeopleSpaceWidgetManager {
|
||||
.collect(Collectors.toMap(
|
||||
Function.identity(),
|
||||
id -> getAugmentedTileForExistingWidget(id, groupedNotifications)))
|
||||
.forEach((id, tile) ->
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, id, tile));
|
||||
.forEach((id, tile) -> updateAppWidgetOptionsAndViewOptional(id, tile));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception updating widgets: " + e);
|
||||
}
|
||||
@@ -341,16 +441,20 @@ public class PeopleSpaceWidgetManager {
|
||||
/**
|
||||
* Augments {@code tile} based on notifications returned from {@code notificationEntryManager}.
|
||||
*/
|
||||
public PeopleSpaceTile augmentTileFromNotificationEntryManager(PeopleSpaceTile tile) {
|
||||
public PeopleSpaceTile augmentTileFromNotificationEntryManager(PeopleSpaceTile tile,
|
||||
Optional<Integer> appWidgetId) {
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
Log.d(TAG, "Augmenting tile from NotificationEntryManager widget: " + key.toString());
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"Augmenting tile from NotificationEntryManager widget: " + key.toString());
|
||||
}
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications =
|
||||
getGroupedConversationNotifications();
|
||||
String contactUri = null;
|
||||
if (tile.getContactUri() != null) {
|
||||
contactUri = tile.getContactUri().toString();
|
||||
}
|
||||
return augmentTileFromNotifications(tile, key, contactUri, notifications);
|
||||
return augmentTileFromNotifications(tile, key, contactUri, notifications, appWidgetId);
|
||||
}
|
||||
|
||||
/** Returns active and pending notifications grouped by {@link PeopleTileKey}. */
|
||||
@@ -380,9 +484,11 @@ public class PeopleSpaceWidgetManager {
|
||||
|
||||
/** Augments {@code tile} based on {@code notifications}, matching {@code contactUri}. */
|
||||
public PeopleSpaceTile augmentTileFromNotifications(PeopleSpaceTile tile, PeopleTileKey key,
|
||||
String contactUri, Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
|
||||
String contactUri,
|
||||
Map<PeopleTileKey, Set<NotificationEntry>> notifications,
|
||||
Optional<Integer> appWidgetId) {
|
||||
if (DEBUG) Log.d(TAG, "Augmenting tile from notifications. Tile key: " + key.toString());
|
||||
boolean hasReadContactsPermission = mPackageManager.checkPermission(READ_CONTACTS,
|
||||
boolean hasReadContactsPermission = mPackageManager.checkPermission(READ_CONTACTS,
|
||||
tile.getPackageName()) == PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
List<NotificationEntry> notificationsByUri = new ArrayList<>();
|
||||
@@ -413,7 +519,8 @@ public class PeopleSpaceWidgetManager {
|
||||
NotificationEntry highestPriority = getHighestPriorityNotification(allNotifications);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "Augmenting tile from notification, key: " + key.toString());
|
||||
return augmentTileFromNotification(mContext, tile, key, highestPriority, messagesCount);
|
||||
return augmentTileFromNotification(mContext, tile, key, highestPriority, messagesCount,
|
||||
appWidgetId);
|
||||
}
|
||||
|
||||
/** Returns an augmented tile for an existing widget. */
|
||||
@@ -434,7 +541,8 @@ public class PeopleSpaceWidgetManager {
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
if (DEBUG) Log.d(TAG, "Existing widget: " + widgetId + ". Tile key: " + key.toString());
|
||||
return Optional.ofNullable(
|
||||
augmentTileFromNotifications(tile, key, contactUriString, notifications));
|
||||
augmentTileFromNotifications(tile, key, contactUriString, notifications,
|
||||
Optional.of(widgetId)));
|
||||
}
|
||||
|
||||
/** Returns stored widgets for the conversation specified. */
|
||||
@@ -552,10 +660,8 @@ public class PeopleSpaceWidgetManager {
|
||||
.setStatuses(conversation.getStatuses())
|
||||
.setLastInteractionTimestamp(conversation.getLastEventTimestamp())
|
||||
.setIsImportantConversation(conversation.getParentNotificationChannel() != null
|
||||
&& conversation.getParentNotificationChannel().isImportantConversation())
|
||||
.build();
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId,
|
||||
updatedTile.build());
|
||||
&& conversation.getParentNotificationChannel().isImportantConversation());
|
||||
updateAppWidgetOptionsAndView(appWidgetId, updatedTile.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -640,11 +746,11 @@ public class PeopleSpaceWidgetManager {
|
||||
/** Adds a widget based on {@code key} mapped to {@code appWidgetId}. */
|
||||
public void addNewWidget(int appWidgetId, PeopleTileKey key) {
|
||||
if (DEBUG) Log.d(TAG, "addNewWidget called with key for appWidgetId: " + appWidgetId);
|
||||
PeopleSpaceTile tile = getTileFromPersistentStorage(key);
|
||||
PeopleSpaceTile tile = getTileFromPersistentStorage(key, appWidgetId);
|
||||
if (tile == null) {
|
||||
return;
|
||||
}
|
||||
tile = augmentTileFromNotificationEntryManager(tile);
|
||||
tile = augmentTileFromNotificationEntryManager(tile, Optional.of(appWidgetId));
|
||||
|
||||
PeopleTileKey existingKeyIfStored;
|
||||
synchronized (mLock) {
|
||||
@@ -665,6 +771,8 @@ public class PeopleSpaceWidgetManager {
|
||||
PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
|
||||
tile.getContactUri());
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
|
||||
registerConversationListenerIfNeeded(appWidgetId, key);
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + key.toString());
|
||||
mLauncherApps.cacheShortcuts(tile.getPackageName(),
|
||||
@@ -674,23 +782,17 @@ public class PeopleSpaceWidgetManager {
|
||||
Log.w(TAG, "Exception caching shortcut:" + e);
|
||||
}
|
||||
|
||||
PeopleSpaceUtils.updateAppWidgetOptionsAndView(
|
||||
mAppWidgetManager, mContext, appWidgetId, tile);
|
||||
mPeopleSpaceWidgetProvider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId});
|
||||
updateAppWidgetOptionsAndView(appWidgetId, tile);
|
||||
}
|
||||
|
||||
/** Registers a conversation listener for {@code appWidgetId} if not already registered. */
|
||||
public void registerConversationListenerIfNeeded(int widgetId,
|
||||
PeopleSpaceWidgetProvider.TileConversationListener newListener) {
|
||||
public void registerConversationListenerIfNeeded(int widgetId, PeopleTileKey key) {
|
||||
// Retrieve storage needed for registration.
|
||||
PeopleTileKey key;
|
||||
synchronized (mLock) {
|
||||
key = getKeyFromStorageByWidgetId(widgetId);
|
||||
if (!key.isValid()) {
|
||||
if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
|
||||
return;
|
||||
}
|
||||
if (!key.isValid()) {
|
||||
if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
|
||||
return;
|
||||
}
|
||||
TileConversationListener newListener = new TileConversationListener();
|
||||
synchronized (mListeners) {
|
||||
if (mListeners.containsKey(key)) {
|
||||
if (DEBUG) Log.d(TAG, "Already registered listener");
|
||||
@@ -760,7 +862,7 @@ public class PeopleSpaceWidgetManager {
|
||||
|
||||
/** Unregisters the conversation listener for {@code appWidgetId}. */
|
||||
private void unregisterConversationListener(PeopleTileKey key, int appWidgetId) {
|
||||
PeopleSpaceWidgetProvider.TileConversationListener registeredListener;
|
||||
TileConversationListener registeredListener;
|
||||
synchronized (mListeners) {
|
||||
registeredListener = mListeners.get(key);
|
||||
if (registeredListener == null) {
|
||||
@@ -875,9 +977,153 @@ public class PeopleSpaceWidgetManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
PeopleSpaceTile augmentedTile = augmentTileFromNotificationEntryManager(tile);
|
||||
PeopleSpaceTile augmentedTile = augmentTileFromNotificationEntryManager(tile,
|
||||
Optional.empty());
|
||||
|
||||
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
|
||||
return new PeopleTileViewHelper(mContext, augmentedTile, 0, options).getViews();
|
||||
return new PeopleTileViewHelper(mContext, augmentedTile, 0, options,
|
||||
new PeopleTileKey(augmentedTile)).getViews();
|
||||
}
|
||||
|
||||
protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (DEBUG) Log.d(TAG, "Update widgets from: " + action);
|
||||
mBgExecutor.execute(() -> updateWidgetsOnStateChange(action));
|
||||
}
|
||||
};
|
||||
|
||||
/** Updates any app widget based on the current state. */
|
||||
@VisibleForTesting
|
||||
void updateWidgetsOnStateChange(String entryPoint) {
|
||||
int[] appWidgetIds = mAppWidgetManager.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
|
||||
if (appWidgetIds == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (mLock) {
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
|
||||
if (tile == null) {
|
||||
Log.e(TAG, "Matching conversation not found for shortcut ID");
|
||||
} else {
|
||||
tile = updateWithCurrentState(tile, entryPoint);
|
||||
}
|
||||
updateAppWidgetOptionsAndView(appWidgetId, tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks the current state of {@code tile} dependencies, updating fields as necessary. */
|
||||
@Nullable
|
||||
private PeopleSpaceTile updateWithCurrentState(PeopleSpaceTile tile,
|
||||
String entryPoint) {
|
||||
PeopleSpaceTile.Builder updatedTile = tile.toBuilder();
|
||||
try {
|
||||
switch (entryPoint) {
|
||||
case NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED:
|
||||
updatedTile.setNotificationPolicyState(getNotificationPolicyState());
|
||||
break;
|
||||
case Intent.ACTION_PACKAGES_SUSPENDED:
|
||||
case Intent.ACTION_PACKAGES_UNSUSPENDED:
|
||||
updatedTile.setIsPackageSuspended(getPackageSuspended(tile));
|
||||
break;
|
||||
case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
|
||||
case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
|
||||
case Intent.ACTION_USER_UNLOCKED:
|
||||
updatedTile.setIsUserQuieted(getUserQuieted(tile));
|
||||
break;
|
||||
case Intent.ACTION_LOCALE_CHANGED:
|
||||
break;
|
||||
case ACTION_BOOT_COMPLETED:
|
||||
default:
|
||||
updatedTile.setIsUserQuieted(getUserQuieted(tile)).setIsPackageSuspended(
|
||||
getPackageSuspended(tile)).setNotificationPolicyState(
|
||||
getNotificationPolicyState());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Package no longer found for tile: " + tile.toString() + e);
|
||||
return null;
|
||||
}
|
||||
return updatedTile.build();
|
||||
}
|
||||
|
||||
private boolean getPackageSuspended(PeopleSpaceTile tile) throws Exception {
|
||||
boolean packageSuspended = !TextUtils.isEmpty(tile.getPackageName())
|
||||
&& mPackageManager.isPackageSuspended(tile.getPackageName());
|
||||
if (DEBUG) Log.d(TAG, "Package suspended: " + packageSuspended);
|
||||
return packageSuspended;
|
||||
}
|
||||
|
||||
private boolean getUserQuieted(PeopleSpaceTile tile) {
|
||||
boolean workProfileQuieted =
|
||||
tile.getUserHandle() != null && mUserManager.isQuietModeEnabled(
|
||||
tile.getUserHandle());
|
||||
if (DEBUG) Log.d(TAG, "Work profile quiet: " + workProfileQuieted);
|
||||
return workProfileQuieted;
|
||||
}
|
||||
|
||||
private int getNotificationPolicyState() {
|
||||
NotificationManager.Policy policy = mNotificationManager.getNotificationPolicy();
|
||||
boolean suppressVisualEffects =
|
||||
NotificationManager.Policy.areAllVisualEffectsSuppressed(
|
||||
policy.suppressedVisualEffects);
|
||||
int notificationPolicyState = 0;
|
||||
switch (mNotificationManager.getCurrentInterruptionFilter()) {
|
||||
case INTERRUPTION_FILTER_ALL:
|
||||
if (DEBUG) Log.d(TAG, "All interruptions allowed");
|
||||
return PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
case INTERRUPTION_FILTER_PRIORITY:
|
||||
if (policy.allowConversations()) {
|
||||
// If the user sees notifications in DND, show notifications in tiles in DND.
|
||||
if (!suppressVisualEffects) {
|
||||
if (DEBUG) Log.d(TAG, "Visual effects not suppressed.");
|
||||
return PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
}
|
||||
if (policy.priorityConversationSenders == CONVERSATION_SENDERS_ANYONE) {
|
||||
if (DEBUG) Log.d(TAG, "All conversations allowed");
|
||||
// We only show conversations, so we can show everything.
|
||||
return PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
} else if (policy.priorityConversationSenders
|
||||
== NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT) {
|
||||
if (DEBUG) Log.d(TAG, "Important conversations allowed");
|
||||
notificationPolicyState |= PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
|
||||
}
|
||||
}
|
||||
if (policy.allowMessages()) {
|
||||
switch (policy.allowMessagesFrom()) {
|
||||
case ZenModeConfig.SOURCE_CONTACT:
|
||||
if (DEBUG) Log.d(TAG, "All contacts allowed");
|
||||
notificationPolicyState |= PeopleSpaceTile.SHOW_CONTACTS;
|
||||
return notificationPolicyState;
|
||||
case ZenModeConfig.SOURCE_STAR:
|
||||
if (DEBUG) Log.d(TAG, "Starred contacts allowed");
|
||||
notificationPolicyState |= PeopleSpaceTile.SHOW_STARRED_CONTACTS;
|
||||
return notificationPolicyState;
|
||||
case ZenModeConfig.SOURCE_ANYONE:
|
||||
default:
|
||||
if (DEBUG) Log.d(TAG, "All messages allowed");
|
||||
return PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
}
|
||||
}
|
||||
if (notificationPolicyState != 0) {
|
||||
if (DEBUG) Log.d(TAG, "Return block state: " + notificationPolicyState);
|
||||
return notificationPolicyState;
|
||||
}
|
||||
// If only alarms or nothing can bypass DND, the tile shouldn't show conversations.
|
||||
case INTERRUPTION_FILTER_NONE:
|
||||
case INTERRUPTION_FILTER_ALARMS:
|
||||
default:
|
||||
// If the user sees notifications in DND, show notifications in tiles in DND.
|
||||
if (!suppressVisualEffects) {
|
||||
if (DEBUG) Log.d(TAG, "Visual effects not suppressed.");
|
||||
return PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Block conversations");
|
||||
return PeopleSpaceTile.BLOCK_CONVERSATIONS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package com.android.systemui.people.widget;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.PeopleManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
@@ -28,6 +25,8 @@ import android.util.Log;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** People Space Widget Provider class. */
|
||||
public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
private static final String TAG = "PeopleSpaceWidgetPvd";
|
||||
@@ -38,25 +37,11 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
public static final String EXTRA_USER_HANDLE = "extra_user_handle";
|
||||
public static final String EXTRA_NOTIFICATION_KEY = "extra_notification_key";
|
||||
|
||||
public PeopleSpaceWidgetManager peopleSpaceWidgetManager;
|
||||
public PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
|
||||
/** Listener for the shortcut data changes. */
|
||||
public class TileConversationListener implements PeopleManager.ConversationListener {
|
||||
|
||||
@Override
|
||||
public void onConversationUpdate(@NonNull ConversationChannel conversation) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"Received updated conversation: "
|
||||
+ conversation.getShortcutInfo().getLabel());
|
||||
}
|
||||
if (peopleSpaceWidgetManager == null) {
|
||||
// This shouldn't happen since onUpdate is called at reboot.
|
||||
Log.e(TAG, "Skipping conversation update: WidgetManager uninitialized");
|
||||
return;
|
||||
}
|
||||
peopleSpaceWidgetManager.updateWidgetsWithConversationChanged(conversation);
|
||||
}
|
||||
@Inject
|
||||
PeopleSpaceWidgetProvider(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
|
||||
mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
|
||||
}
|
||||
|
||||
/** Called when widget updates. */
|
||||
@@ -65,15 +50,8 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "onUpdate called");
|
||||
ensurePeopleSpaceWidgetManagerInitialized(context);
|
||||
peopleSpaceWidgetManager.updateWidgets(appWidgetIds);
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
|
||||
PeopleSpaceWidgetProvider.TileConversationListener
|
||||
newListener = new PeopleSpaceWidgetProvider.TileConversationListener();
|
||||
peopleSpaceWidgetManager.registerConversationListenerIfNeeded(appWidgetId,
|
||||
newListener);
|
||||
}
|
||||
ensurePeopleSpaceWidgetManagerInitialized();
|
||||
mPeopleSpaceWidgetManager.updateWidgets(appWidgetIds);
|
||||
}
|
||||
|
||||
/** Called when widget updates. */
|
||||
@@ -81,25 +59,23 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId, Bundle newOptions) {
|
||||
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
|
||||
ensurePeopleSpaceWidgetManagerInitialized(context);
|
||||
peopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
|
||||
ensurePeopleSpaceWidgetManagerInitialized();
|
||||
mPeopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
super.onDeleted(context, appWidgetIds);
|
||||
ensurePeopleSpaceWidgetManagerInitialized(context);
|
||||
peopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
|
||||
ensurePeopleSpaceWidgetManagerInitialized();
|
||||
mPeopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
|
||||
}
|
||||
|
||||
private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
|
||||
if (peopleSpaceWidgetManager == null) {
|
||||
peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
|
||||
}
|
||||
private void ensurePeopleSpaceWidgetManagerInitialized() {
|
||||
mPeopleSpaceWidgetManager.init();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager manager) {
|
||||
peopleSpaceWidgetManager = manager;
|
||||
mPeopleSpaceWidgetManager = manager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -59,6 +58,7 @@ import androidx.test.filters.SmallTest;
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
@@ -73,6 +73,7 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@SmallTest
|
||||
@@ -188,6 +189,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
@Mock
|
||||
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
|
||||
private Bundle mOptions;
|
||||
|
||||
@@ -212,8 +215,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
when(resources.getConfiguration()).thenReturn(configuration);
|
||||
when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
|
||||
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
|
||||
when(mMockContentResolver.query(any(Uri.class), any(), anyString(), any(),
|
||||
isNull())).thenReturn(mMockCursor);
|
||||
when(mMockContentResolver.query(any(Uri.class), any(), any(), any(),
|
||||
any())).thenReturn(mMockCursor);
|
||||
when(mMockContext.getString(R.string.birthday_status)).thenReturn(
|
||||
mContext.getString(R.string.birthday_status));
|
||||
when(mMockContext.getString(R.string.basic_status)).thenReturn(
|
||||
@@ -236,7 +239,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.build();
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromNotification(mContext, tile, key, mNotificationEntry1, 0);
|
||||
.augmentTileFromNotification(mContext, tile, key, mNotificationEntry1, 0,
|
||||
Optional.empty());
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
assertThat(actual.getNotificationSender()).isEqualTo(null);
|
||||
@@ -275,7 +279,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.build();
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromNotification(mContext, tile, key, notificationEntry, 0);
|
||||
.augmentTileFromNotification(mContext, tile, key, notificationEntry, 0,
|
||||
Optional.empty());
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
|
||||
assertThat(actual.getNotificationSender().toString()).isEqualTo("name");
|
||||
@@ -291,7 +296,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
.build();
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
PeopleSpaceTile actual = PeopleSpaceUtils
|
||||
.augmentTileFromNotification(mContext, tile, key, mNotificationEntry3, 0);
|
||||
.augmentTileFromNotification(mContext, tile, key, mNotificationEntry3, 0,
|
||||
Optional.empty());
|
||||
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(null);
|
||||
}
|
||||
@@ -308,10 +314,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
Map<Integer, PeopleSpaceTile> widgetIdToTile = Map.of(WIDGET_ID_WITH_SHORTCUT,
|
||||
new PeopleSpaceTile.Builder(mShortcutInfoWithoutPerson,
|
||||
mContext.getSystemService(LauncherApps.class)).build());
|
||||
PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
|
||||
PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
|
||||
widgetIdToTile, widgetIdsArray);
|
||||
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
verify(mPeopleSpaceWidgetManager, never()).updateAppWidgetOptionsAndView(
|
||||
eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@@ -328,10 +335,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
new PeopleSpaceTile.Builder(mShortcutInfoWithoutPerson,
|
||||
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
|
||||
mContext.getString(R.string.birthday_status)).build());
|
||||
PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
|
||||
PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
|
||||
widgetIdToTile, widgetIdsArray);
|
||||
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
|
||||
eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@@ -363,10 +371,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
new PeopleSpaceTile.Builder(mShortcutInfo,
|
||||
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
|
||||
mContext.getString(R.string.birthday_status)).build());
|
||||
PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
|
||||
PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
|
||||
widgetIdToTile, widgetIdsArray);
|
||||
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
|
||||
eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@@ -375,6 +384,9 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
|
||||
when(mMockCursor.moveToNext()).thenReturn(true, false, true, false);
|
||||
when(mMockCursor.getString(eq(TEST_COLUMN_INDEX))).thenReturn(TEST_LOOKUP_KEY);
|
||||
when(mMockCursor.getInt(eq(TEST_COLUMN_INDEX + 1))).thenReturn(1);
|
||||
when(mMockCursor.getColumnIndex(eq(ContactsContract.Contacts.STARRED))).thenReturn(
|
||||
TEST_COLUMN_INDEX + 1);
|
||||
when(mMockCursor.getColumnIndex(eq(ContactsContract.CommonDataKinds.Event.LOOKUP_KEY)
|
||||
)).thenReturn(TEST_COLUMN_INDEX);
|
||||
|
||||
@@ -383,10 +395,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
|
||||
new PeopleSpaceTile.Builder(mShortcutInfo,
|
||||
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
|
||||
mContext.getString(R.string.birthday_status)).build());
|
||||
PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
|
||||
PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
|
||||
widgetIdToTile, widgetIdsArray);
|
||||
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
|
||||
eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,20 @@ import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
|
||||
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
|
||||
import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
|
||||
import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
|
||||
import static android.app.people.PeopleSpaceTile.BLOCK_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_CONTACTS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_STARRED_CONTACTS;
|
||||
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
|
||||
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT;
|
||||
import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -53,6 +60,7 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.people.widget.PeopleTileKey;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -148,14 +156,14 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
TextView textView = mock(TextView.class);
|
||||
when(textView.getLineHeight()).thenReturn(16);
|
||||
when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
|
||||
mPeopleTileViewHelper = new PeopleTileViewHelper(mContext,
|
||||
PERSON_TILE, 0, mOptions);
|
||||
mPeopleTileViewHelper = getPeopleTileViewHelper(
|
||||
PERSON_TILE, mOptions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithLastInteractionTimeUnderOneDayHidden() {
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
// Not showing last interaction.
|
||||
@@ -165,8 +173,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
// Not showing last interaction.
|
||||
@@ -178,8 +186,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
PeopleSpaceTile tileWithLastInteraction =
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setLastInteractionTimestamp(
|
||||
123445L).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithLastInteraction, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithLastInteraction, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -197,8 +205,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithLastInteraction, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithLastInteraction, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show name over predefined icon.
|
||||
@@ -214,8 +222,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithLastInteraction, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithLastInteraction, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -240,8 +248,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
new ConversationStatus.Builder(
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
|
||||
ACTIVITY_GAME).build())).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithAvailabilityAndNewStory, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -257,8 +265,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithAvailabilityAndNewStory, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show name rather than game type.
|
||||
@@ -274,8 +282,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithAvailabilityAndNewStory, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -298,8 +306,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
|
||||
ACTIVITY_BIRTHDAY).build())).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -318,8 +326,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -336,8 +344,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -362,8 +370,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
|
||||
Arrays.asList(GAME_STATUS,
|
||||
NEW_STORY_WITH_AVAILABILITY)).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -381,8 +389,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -399,8 +407,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusTemplate, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithStatusTemplate, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -419,6 +427,120 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
assertThat(statusContent.getMaxLines()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithPackageSuspended() {
|
||||
PeopleSpaceTile tile = PERSON_TILE.toBuilder()
|
||||
.setIsPackageSuspended(true)
|
||||
.build();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tile, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithUserQuieted() {
|
||||
PeopleSpaceTile tile = PERSON_TILE.toBuilder()
|
||||
.setIsUserQuieted(true)
|
||||
.build();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tile, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithDndBlocking() {
|
||||
PeopleSpaceTile tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(BLOCK_CONVERSATIONS)
|
||||
.build();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(BLOCK_CONVERSATIONS)
|
||||
.setCanBypassDnd(true)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
|
||||
.setIsImportantConversation(true)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_STARRED_CONTACTS)
|
||||
.setContactAffinity(VALID_CONTACT)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_STARRED_CONTACTS)
|
||||
.setContactAffinity(STARRED_CONTACT)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_CONTACTS)
|
||||
.setContactAffinity(STARRED_CONTACT)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_CONTACTS)
|
||||
.setContactAffinity(VALID_CONTACT)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
|
||||
tileWithDndBlocking = PERSON_TILE.toBuilder()
|
||||
.setNotificationPolicyState(SHOW_CONTACTS)
|
||||
.build();
|
||||
views = getPeopleTileViewHelper(
|
||||
tileWithDndBlocking, mOptions).getViews();
|
||||
result = views.apply(mContext, null);
|
||||
|
||||
assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRemoteViewsWithMissedCallNotification() {
|
||||
PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
|
||||
@@ -426,8 +548,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
.setNotificationCategory(CATEGORY_MISSED_CALL)
|
||||
.setNotificationContent(MISSED_CALL)
|
||||
.build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithMissedCallNotification, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithMissedCallNotification, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -446,8 +568,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithMissedCallNotification, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithMissedCallNotification, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -463,8 +585,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithMissedCallNotification, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithMissedCallNotification, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -489,8 +611,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
.setNotificationDataUri(null)
|
||||
.setStatuses(Arrays.asList(GAME_STATUS,
|
||||
NEW_STORY_WITH_AVAILABILITY)).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -512,8 +634,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -531,8 +653,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -561,8 +683,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
.setNotificationDataUri(null)
|
||||
.setStatuses(Arrays.asList(GAME_STATUS,
|
||||
NEW_STORY_WITH_AVAILABILITY)).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -588,8 +710,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -607,8 +729,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -642,8 +764,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
.setStatuses(Arrays.asList(GAME_STATUS,
|
||||
NEW_STORY_WITH_AVAILABILITY))
|
||||
.setMessagesCount(2).build();
|
||||
RemoteViews views = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews views = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View result = views.apply(mContext, null);
|
||||
|
||||
TextView name = (TextView) result.findViewById(R.id.name);
|
||||
@@ -665,8 +787,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_width_for_medium) - 1);
|
||||
RemoteViews smallView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews smallView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View smallResult = smallView.apply(mContext, null);
|
||||
|
||||
// Show icon instead of name.
|
||||
@@ -684,8 +806,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
getSizeInDp(R.dimen.required_width_for_large));
|
||||
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
|
||||
getSizeInDp(R.dimen.required_height_for_large));
|
||||
RemoteViews largeView = new PeopleTileViewHelper(mContext,
|
||||
tileWithStatusAndNotification, 0, mOptions).getViews();
|
||||
RemoteViews largeView = getPeopleTileViewHelper(
|
||||
tileWithStatusAndNotification, mOptions).getViews();
|
||||
View largeResult = largeView.apply(mContext, null);
|
||||
|
||||
name = (TextView) largeResult.findViewById(R.id.name);
|
||||
@@ -858,4 +980,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
|
||||
return (int) (mContext.getResources().getDimension(dimenResourceId)
|
||||
/ mContext.getResources().getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
private PeopleTileViewHelper getPeopleTileViewHelper(PeopleSpaceTile tile, Bundle options) {
|
||||
return new PeopleTileViewHelper(mContext, tile, 0, options,
|
||||
new PeopleTileKey(tile.getId(), 0, tile.getPackageName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,32 @@ import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
import static android.app.Notification.EXTRA_PEOPLE_LIST;
|
||||
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
|
||||
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
|
||||
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
|
||||
import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
|
||||
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
|
||||
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
|
||||
import static android.app.people.PeopleSpaceTile.BLOCK_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_CONTACTS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
|
||||
import static android.app.people.PeopleSpaceTile.SHOW_STARRED_CONTACTS;
|
||||
import static android.content.Intent.ACTION_BOOT_COMPLETED;
|
||||
import static android.content.Intent.ACTION_PACKAGES_SUSPENDED;
|
||||
import static android.content.PermissionChecker.PERMISSION_GRANTED;
|
||||
import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
|
||||
import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
|
||||
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
|
||||
@@ -73,6 +94,7 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.service.notification.ConversationChannelWrapper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -89,6 +111,7 @@ import com.android.systemui.statusbar.notification.collection.NoManSimulator;
|
||||
import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -99,12 +122,14 @@ import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -158,6 +183,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
// Same contact uri.
|
||||
.setContactUri(URI)
|
||||
.build();
|
||||
private static final int ALL_SUPPRESSED_VISUAL_EFFECTS = SUPPRESSED_EFFECT_SCREEN_OFF
|
||||
| SUPPRESSED_EFFECT_SCREEN_ON
|
||||
| SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
| SUPPRESSED_EFFECT_AMBIENT
|
||||
| SUPPRESSED_EFFECT_STATUS_BAR
|
||||
| SUPPRESSED_EFFECT_BADGE
|
||||
| SUPPRESSED_EFFECT_LIGHTS
|
||||
| SUPPRESSED_EFFECT_PEEK
|
||||
| SUPPRESSED_EFFECT_NOTIFICATION_LIST;
|
||||
|
||||
private ShortcutInfo mShortcutInfo;
|
||||
private NotificationEntry mNotificationEntry;
|
||||
|
||||
@@ -182,9 +217,13 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private INotificationManager mNotificationManager;
|
||||
private INotificationManager mINotificationManager;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private NotificationManager mNotificationManager;
|
||||
@Mock
|
||||
private NotificationManager.Policy mNotificationPolicy;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
|
||||
@@ -194,19 +233,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
private final NoManSimulator mNoMan = new NoManSimulator();
|
||||
private final FakeSystemClock mClock = new FakeSystemClock();
|
||||
|
||||
private PeopleSpaceWidgetProvider mProvider;
|
||||
private final FakeExecutor mFakeExecutor = new FakeExecutor(mClock);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLauncherApps = mock(LauncherApps.class);
|
||||
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
|
||||
mManager = new PeopleSpaceWidgetManager(mContext);
|
||||
mProvider = new PeopleSpaceWidgetProvider();
|
||||
mProvider.setPeopleSpaceWidgetManager(mManager);
|
||||
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
|
||||
mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider,
|
||||
mUserManager, mNotificationManager);
|
||||
mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
|
||||
mPeopleManager, mLauncherApps, mNotificationEntryManager, mPackageManager,
|
||||
mUserManager, mINotificationManager, mNotificationManager, mFakeExecutor);
|
||||
mManager.attach(mListenerService);
|
||||
|
||||
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
|
||||
@@ -218,7 +254,19 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
|
||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
||||
.thenReturn(new Bundle());
|
||||
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
|
||||
when(mPackageManager.isPackageSuspended(any())).thenReturn(false);
|
||||
setFinalField("suppressedVisualEffects", ALL_SUPPRESSED_VISUAL_EFFECTS);
|
||||
when(mNotificationPolicy.allowConversationsFrom()).thenReturn(CONVERSATION_SENDERS_ANYONE);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(false);
|
||||
when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_ANYONE);
|
||||
when(mNotificationPolicy.allowMessages()).thenReturn(false);
|
||||
when(mNotificationManager.getNotificationPolicy()).thenReturn(mNotificationPolicy);
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_ALL);
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
when(mMockContext.getPackageName()).thenReturn(TEST_PACKAGE_A);
|
||||
when(mMockContext.getUserId()).thenReturn(0);
|
||||
@@ -242,7 +290,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
|
||||
SHORTCUT_ID + 2,
|
||||
true, 1);
|
||||
when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
new ParceledListSlice(Arrays.asList(
|
||||
newerNonImportantConversation, newerImportantConversation,
|
||||
olderImportantConversation)));
|
||||
@@ -280,7 +328,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
|
||||
SHORTCUT_ID + 2,
|
||||
true, 1);
|
||||
when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
new ParceledListSlice(Arrays.asList(
|
||||
newerNonImportantConversation, newerImportantConversation,
|
||||
olderImportantConversation)));
|
||||
@@ -306,7 +354,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
|
||||
SHORTCUT_ID + 2,
|
||||
true, 1);
|
||||
when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
|
||||
new ParceledListSlice(Arrays.asList(
|
||||
newerNonImportantConversation, newerImportantConversation,
|
||||
olderImportantConversation)));
|
||||
@@ -1027,8 +1075,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
|
||||
throws Exception {
|
||||
addSecondWidgetForPersonTile();
|
||||
mProvider.onUpdate(mContext, mAppWidgetManager,
|
||||
new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
mManager.updateWidgets(new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
|
||||
// Delete only one widget for the conversation.
|
||||
mManager.deleteWidgets(new int[]{WIDGET_ID_WITH_SHORTCUT});
|
||||
@@ -1050,7 +1097,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
|
||||
|
||||
// Delete all widgets for the conversation.
|
||||
mProvider.onDeleted(mContext, new int[]{SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
mManager.deleteWidgets(new int[]{SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
|
||||
// Check deleted storage.
|
||||
SharedPreferences secondWidgetSp = mContext.getSharedPreferences(
|
||||
@@ -1154,7 +1201,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(channel);
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
|
||||
assertThat(tile.getId()).isEqualTo(key.getShortcutId());
|
||||
}
|
||||
|
||||
@@ -1162,7 +1209,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testGetPeopleTileFromPersistentStorageNoConversation() throws RemoteException {
|
||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
|
||||
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
|
||||
PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
|
||||
assertThat(tile).isNull();
|
||||
}
|
||||
|
||||
@@ -1195,18 +1242,25 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testAugmentTileFromNotifications() {
|
||||
clearStorage();
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), null)).isEqualTo(null);
|
||||
PeopleSpaceTile tile =
|
||||
new PeopleSpaceTile
|
||||
.Builder(SHORTCUT_ID, "userName", ICON, new Intent())
|
||||
.setPackageName(TEST_PACKAGE_A)
|
||||
.setUserHandle(new UserHandle(0))
|
||||
.build();
|
||||
|
||||
PeopleTileKey key = new PeopleTileKey(tile);
|
||||
PeopleSpaceTile actual = mManager.augmentTileFromNotifications(tile, key, EMPTY_STRING,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry),
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))));
|
||||
Map.of(new PeopleTileKey(mNotificationEntry),
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))),
|
||||
Optional.of(WIDGET_ID_WITH_SHORTCUT));
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), null)).isEqualTo(
|
||||
URI.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1221,7 +1275,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
PeopleSpaceTile actual = mManager
|
||||
.augmentTileFromNotifications(tile, key, EMPTY_STRING,
|
||||
Map.of(new PeopleTileKey(mNotificationEntry),
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))));
|
||||
new HashSet<>(Collections.singleton(mNotificationEntry))),
|
||||
Optional.empty());
|
||||
|
||||
assertThat(actual.getNotificationContent()).isEqualTo(null);
|
||||
}
|
||||
@@ -1238,7 +1293,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.thenReturn(List.of(mNotificationEntry));
|
||||
|
||||
PeopleSpaceTile actual =
|
||||
mManager.augmentTileFromNotificationEntryManager(tile);
|
||||
mManager.augmentTileFromNotificationEntryManager(tile,
|
||||
Optional.of(WIDGET_ID_WITH_SHORTCUT));
|
||||
|
||||
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
|
||||
|
||||
@@ -1246,6 +1302,202 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
.getVisibleNotifications();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChange() {
|
||||
mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.isPackageSuspended()).isFalse();
|
||||
assertThat(tile.isUserQuieted()).isFalse();
|
||||
assertThat(tile.canBypassDnd()).isFalse();
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeWithUserQuieted() {
|
||||
when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.isPackageSuspended()).isFalse();
|
||||
assertThat(tile.isUserQuieted()).isTrue();
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeWithPackageSuspended() throws Exception {
|
||||
when(mPackageManager.isPackageSuspended(any())).thenReturn(true);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(ACTION_PACKAGES_SUSPENDED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.isPackageSuspended()).isTrue();
|
||||
assertThat(tile.isUserQuieted()).isFalse();
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeNotInDnd() {
|
||||
int expected = 0;
|
||||
mManager.updateWidgetsOnStateChange(NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllConversations() {
|
||||
int expected = 0;
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(true);
|
||||
setFinalField("priorityConversationSenders", CONVERSATION_SENDERS_ANYONE);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowOnlyImportantConversations() {
|
||||
int expected = 0;
|
||||
// Only allow important conversations.
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(true);
|
||||
setFinalField("priorityConversationSenders", CONVERSATION_SENDERS_IMPORTANT);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(
|
||||
expected | SHOW_IMPORTANT_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowNoConversations() {
|
||||
int expected = 0;
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(false);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | BLOCK_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowNoConversationsAllowContactMessages() {
|
||||
int expected = 0;
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(false);
|
||||
when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_CONTACT);
|
||||
when(mNotificationPolicy.allowMessages()).thenReturn(true);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONTACTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowNoConversationsAllowStarredContactMessages() {
|
||||
int expected = 0;
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_PRIORITY);
|
||||
when(mNotificationPolicy.allowConversations()).thenReturn(false);
|
||||
when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_STAR);
|
||||
when(mNotificationPolicy.allowMessages()).thenReturn(true);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_STARRED_CONTACTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowAlarmsOnly() {
|
||||
int expected = 0;
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_ALARMS);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(NotificationManager
|
||||
.ACTION_INTERRUPTION_FILTER_CHANGED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | BLOCK_CONVERSATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWidgetsOnStateChangeAllowVisualEffectsAndAllowAlarmsOnly() {
|
||||
int expected = 0;
|
||||
// If we show visuals, but just only make sounds for alarms, still show content in tiles.
|
||||
when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
|
||||
INTERRUPTION_FILTER_ALARMS);
|
||||
setFinalField("suppressedVisualEffects", SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
|
||||
| SUPPRESSED_EFFECT_AMBIENT);
|
||||
|
||||
mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
|
||||
assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
|
||||
}
|
||||
|
||||
private void setFinalField(String fieldName, int value) {
|
||||
try {
|
||||
Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(mNotificationPolicy, value);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
|
||||
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
|
||||
|
||||
Reference in New Issue
Block a user