method public String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
+ method @Nullable public android.content.LocusId getLocusId();
method public CharSequence getSettingsText();
method public String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
method @NonNull public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method @Deprecated public android.app.Notification.Builder setLights(@ColorInt int, int, int);
method @NonNull public android.app.Notification.Builder setLocalOnly(boolean);
+ method @NonNull public android.app.Notification.Builder setLocusId(@Nullable android.content.LocusId);
method @NonNull public android.app.Notification.Builder setNumber(int);
method @NonNull public android.app.Notification.Builder setOngoing(boolean);
method @NonNull public android.app.Notification.Builder setOnlyAlertOnce(boolean);
method @Nullable public android.content.Intent getIntent();
method @Nullable public android.content.Intent[] getIntents();
method public long getLastChangedTimestamp();
+ method @Nullable public android.content.LocusId getLocusId();
method @Nullable public CharSequence getLongLabel();
method @NonNull public String getPackage();
method public int getRank();
method @NonNull public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
method @NonNull public android.content.pm.ShortcutInfo.Builder setIntent(@NonNull android.content.Intent);
method @NonNull public android.content.pm.ShortcutInfo.Builder setIntents(@NonNull android.content.Intent[]);
+ method @NonNull public android.content.pm.ShortcutInfo.Builder setLocusId(@NonNull android.content.LocusId);
method @NonNull public android.content.pm.ShortcutInfo.Builder setLongLabel(@NonNull CharSequence);
method @NonNull public android.content.pm.ShortcutInfo.Builder setLongLived();
method @NonNull public android.content.pm.ShortcutInfo.Builder setPerson(@NonNull android.app.Person);
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.contentcapture.ContentCaptureContext;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
private long mTimeout;
private String mShortcutId;
+ private LocusId mLocusId;
private CharSequence mSettingsText;
private BubbleMetadata mBubbleMetadata;
mShortcutId = parcel.readString();
}
+ if (parcel.readInt() != 0) {
+ mLocusId = LocusId.CREATOR.createFromParcel(parcel);
+ }
+
mBadgeIcon = parcel.readInt();
if (parcel.readInt() != 0) {
that.mChannelId = this.mChannelId;
that.mTimeout = this.mTimeout;
that.mShortcutId = this.mShortcutId;
+ that.mLocusId = this.mLocusId;
that.mBadgeIcon = this.mBadgeIcon;
that.mSettingsText = this.mSettingsText;
that.mGroupAlertBehavior = this.mGroupAlertBehavior;
parcel.writeInt(0);
}
+ if (mLocusId != null) {
+ parcel.writeInt(1);
+ mLocusId.writeToParcel(parcel, 0);
+ } else {
+ parcel.writeInt(0);
+ }
+
parcel.writeInt(mBadgeIcon);
if (mSettingsText != null) {
sb.append(" publicVersion=");
sb.append(publicVersion.toString());
}
+ if (this.mLocusId != null) {
+ sb.append(" locusId=");
+ sb.append(this.mLocusId); // LocusId.toString() is PII safe.
+ }
sb.append(")");
return sb.toString();
}
return mShortcutId;
}
+ /**
+ * Gets the {@link LocusId} associated with this notification.
+ *
+ * <p>Used by the device's intelligence services to correlate objects (such as
+ * {@link ShortcutInfo} and {@link ContentCaptureContext}) that are correlated.
+ */
+ @Nullable
+ public LocusId getLocusId() {
+ return mLocusId;
+ }
/**
* Returns the settings text provided to {@link Builder#setSettingsText(CharSequence)}.
}
/**
+ * Sets the {@link LocusId} associated with this notification.
+ *
+ * <p>This method should be called when the {@link LocusId} is used in other places (such
+ * as {@link ShortcutInfo} and {@link ContentCaptureContext}) so the device's intelligence
+ * services can correlate them.
+ */
+ @NonNull
+ public Builder setLocusId(@Nullable LocusId locusId) {
+ mN.mLocusId = locusId;
+ return this;
+ }
+
+ /**
* Sets which icon to display as a badge for this notification.
*
* Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
+import android.app.Notification;
import android.app.Person;
import android.app.TaskStackBuilder;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import android.view.contentcapture.ContentCaptureContext;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
@Nullable
private Person[] mPersons;
+ @Nullable
+ private LocusId mLocusId;
+
private int mRank;
/**
}
mRank = b.mRank;
mExtras = b.mExtras;
+ mLocusId = b.mLocusId;
+
updateTimestamp();
}
mFlags = source.mFlags;
mLastChangedTimestamp = source.mLastChangedTimestamp;
mDisabledReason = source.mDisabledReason;
+ mLocusId = source.mLocusId;
// Just always keep it since it's cheep.
mIconResId = source.mIconResId;
if (source.mExtras != null) {
mExtras = source.mExtras;
}
+
+ if (source.mLocusId != null) {
+ mLocusId = source.mLocusId;
+ }
}
/**
private PersistableBundle mExtras;
+ private LocusId mLocusId;
+
/**
* Old style constructor.
* @hide
}
/**
+ * Sets the {@link LocusId} associated with this shortcut.
+ *
+ * <p>This method should be called when the {@link LocusId} is used in other places (such
+ * as {@link Notification} and {@link ContentCaptureContext}) so the device's intelligence
+ * services can correlate them.
+ */
+ @NonNull
+ public Builder setLocusId(@NonNull LocusId locusId) {
+ mLocusId = Preconditions.checkNotNull(locusId, "locusId cannot be null");
+ return this;
+ }
+
+ /**
* Sets the target activity. A shortcut will be shown along with this activity's icon
* on the launcher.
*
}
/**
+ * Gets the {@link LocusId} associated with this shortcut.
+ *
+ * <p>Used by the device's intelligence services to correlate objects (such as
+ * {@link Notification} and {@link ContentCaptureContext}) that are correlated.
+ */
+ @Nullable
+ public LocusId getLocusId() {
+ return mLocusId;
+ }
+
+ /**
* Return the package name of the publisher app.
*/
@NonNull
}
mPersons = source.readParcelableArray(cl, Person.class);
+ mLocusId = source.readParcelable(cl);
}
@Override
}
dest.writeParcelableArray(mPersons, flags);
+ dest.writeParcelable(mLocusId, flags);
}
public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR =
sb.append(mBitmapPath);
}
+ if (mLocusId != null) {
+ sb.append("locusId="); sb.append(mLocusId); // LocusId.toString() is PII-safe.
+ }
+
sb.append("}");
return sb.toString();
}
Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
long lastChangedTimestamp,
int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason,
- Person[] persons) {
+ Person[] persons, LocusId locusId) {
mUserId = userId;
mId = id;
mPackageName = packageName;
mBitmapPath = bitmapPath;
mDisabledReason = disabledReason;
mPersons = persons;
+ mLocusId = locusId;
}
}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
action.clone().getSemanticAction());
}
+ @Test
+ public void testBuilder_setLocusId() {
+ LocusId locusId = new LocusId("4815162342");
+ Notification notification = new Notification.Builder(mContext, "whatever")
+ .setLocusId(locusId).build();
+ assertEquals(locusId, notification.getLocusId());
+
+ Notification clone = writeAndReadParcelable(notification);
+ assertEquals(locusId, clone.getLocusId());
+ }
+
+ @Test
+ public void testBuilder_setLocusId_null() {
+ Notification notification = new Notification.Builder(mContext, "whatever")
+ .setLocusId(null).build();
+ assertNull(notification.getLocusId());
+
+ Notification clone = writeAndReadParcelable(notification);
+ assertNull(clone.getLocusId());
+ }
+
private Notification.Builder getMediaNotification() {
MediaSession session = new MediaSession(mContext, "test");
return new Notification.Builder(mContext, "color")
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.LocusId;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
flags |= ShortcutInfo.FLAG_SHADOW;
}
+ LocusId locusId = null; // LocusId is not set on XML.
+
return new ShortcutInfo(
- userId, id, packageName, activityComponent, /* icon =*/ null,
+ userId, id, packageName, activityComponent, /* icon= */ null,
title, titleResId, titleResName, text, textResId, textResName,
disabledMessage, disabledMessageResId, disabledMessageResName,
categories,
intents.toArray(new Intent[intents.size()]),
rank, extras, lastChangedTimestamp, flags,
iconResId, iconResName, bitmapPath, disabledReason,
- persons.toArray(new Person[persons.size()]));
+ persons.toArray(new Person[persons.size()]), locusId);
}
private static Intent parseIntent(XmlPullParser parser)
null, // icon res name
null, // bitmap path
disabledReason,
- null /* persons */);
+ null /* persons */,
+ null /* locusId */);
}
private static String parseCategory(ShortcutService service, AttributeSet attrs) {
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
+import android.content.LocusId;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.Callback;
import android.content.pm.ShortcutInfo;
return ret;
}
+ public static LocusId locusId(String id) {
+ return new LocusId(id);
+ }
+
public static void resetAll(Collection<?> mocks) {
for (Object o : mocks) {
reset(o);