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

Commit fd4055bb authored by Mehdi Alizadeh's avatar Mehdi Alizadeh Committed by Android (Google) Code Review
Browse files

Merge "Adds API to set persons and isLongLived in ShortcutInfo"

parents 19d2020d 14242afe
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -11950,6 +11950,9 @@ package android.content.pm {
    method public android.content.pm.ShortcutInfo.Builder setIntent(android.content.Intent);
    method public android.content.pm.ShortcutInfo.Builder setIntents(android.content.Intent[]);
    method public android.content.pm.ShortcutInfo.Builder setLongLabel(java.lang.CharSequence);
    method public android.content.pm.ShortcutInfo.Builder setLongLived();
    method public android.content.pm.ShortcutInfo.Builder setPerson(android.app.Person);
    method public android.content.pm.ShortcutInfo.Builder setPersons(android.app.Person[]);
    method public android.content.pm.ShortcutInfo.Builder setRank(int);
    method public android.content.pm.ShortcutInfo.Builder setShortLabel(java.lang.CharSequence);
  }
+114 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
import android.app.Person;
import android.app.TaskStackBuilder;
import android.content.ComponentName;
import android.content.Context;
@@ -110,6 +111,9 @@ public final class ShortcutInfo implements Parcelable {
     */
    public static final int FLAG_SHADOW = 1 << 12;

    /** @hide */
    public static final int FLAG_LONG_LIVED = 1 << 13;

    /** @hide */
    @IntDef(flag = true, prefix = { "FLAG_" }, value = {
            FLAG_DYNAMIC,
@@ -124,6 +128,8 @@ public final class ShortcutInfo implements Parcelable {
            FLAG_ADAPTIVE_BITMAP,
            FLAG_RETURNED_BY_SERVICE,
            FLAG_ICON_FILE_PENDING_SAVE,
            FLAG_SHADOW,
            FLAG_LONG_LIVED,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ShortcutFlags {}
@@ -344,6 +350,9 @@ public final class ShortcutInfo implements Parcelable {
    @Nullable
    private PersistableBundle[] mIntentPersistableExtrases;

    @Nullable
    private Person[] mPersons;

    private int mRank;

    /**
@@ -399,6 +408,10 @@ public final class ShortcutInfo implements Parcelable {
        mCategories = cloneCategories(b.mCategories);
        mIntents = cloneIntents(b.mIntents);
        fixUpIntentExtras();
        mPersons = clonePersons(b.mPersons);
        if (b.mIsLongLived) {
            setLongLived();
        }
        mRank = b.mRank;
        mExtras = b.mExtras;
        updateTimestamp();
@@ -465,6 +478,20 @@ public final class ShortcutInfo implements Parcelable {
        return ret;
    }

    private static Person[] clonePersons(Person[] persons) {
        if (persons == null) {
            return null;
        }
        final Person[] ret = new Person[persons.length];
        for (int i = 0; i < ret.length; i++) {
            if (persons[i] != null) {
                // Don't need to keep the icon, remove it to save space
                ret[i] = persons[i].toBuilder().setIcon(null).build();
            }
        }
        return ret;
    }

    /**
     * Throws if any of the mandatory fields is not set.
     *
@@ -511,6 +538,7 @@ public final class ShortcutInfo implements Parcelable {
            mDisabledMessage = source.mDisabledMessage;
            mDisabledMessageResId = source.mDisabledMessageResId;
            mCategories = cloneCategories(source.mCategories);
            mPersons = clonePersons(source.mPersons);
            if ((cloneFlags & CLONE_REMOVE_INTENT) == 0) {
                mIntents = cloneIntents(source.mIntents);
                mIntentPersistableExtrases =
@@ -833,6 +861,9 @@ public final class ShortcutInfo implements Parcelable {
        if (source.mCategories != null) {
            mCategories = cloneCategories(source.mCategories);
        }
        if (source.mPersons != null) {
            mPersons = clonePersons(source.mPersons);
        }
        if (source.mIntents != null) {
            mIntents = cloneIntents(source.mIntents);
            mIntentPersistableExtrases =
@@ -901,6 +932,10 @@ public final class ShortcutInfo implements Parcelable {

        private Intent[] mIntents;

        private Person[] mPersons;

        private boolean mIsLongLived;

        private int mRank = RANK_NOT_SET;

        private PersistableBundle mExtras;
@@ -1164,6 +1199,53 @@ public final class ShortcutInfo implements Parcelable {
            return this;
        }

        /**
         * Add a person that is relevant to this shortcut. Alternatively,
         * {@link #setPersons(Person[])} can be used to add multiple persons to a shortcut.
         *
         * <p> This is an optional field, but the addition of person may cause this shortcut to
         * appear more prominently in the user interface (e.g. ShareSheet).
         *
         * <p> A person should usually contain a uri in order to benefit from the ranking boost.
         * However, even if no uri is provided, it's beneficial to provide people in the shortcut,
         * such that listeners and voice only devices can announce and handle them properly.
         *
         * @see Person
         * @see #setPersons(Person[])
         */
        @NonNull
        public Builder setPerson(@NonNull Person person) {
            return setPersons(new Person[]{person});
        }

        /**
         * Sets multiple persons instead of a single person.
         *
         * @see Person
         * @see #setPerson(Person)
         */
        @NonNull
        public Builder setPersons(@NonNull Person[] persons) {
            Preconditions.checkNotNull(persons, "persons cannot be null");
            Preconditions.checkNotNull(persons.length, "persons cannot be empty");
            for (Person person : persons) {
                Preconditions.checkNotNull(person, "persons cannot contain null");
            }
            mPersons = clonePersons(persons);
            return this;
        }

        /**
         * Sets if a shortcut would be valid even if it has been unpublished/invisible by the app
         * (as a dynamic or pinned shortcut). If it is long lived, it can be cached by various
         * system services even after it has been unpublished as a dynamic shortcut.
         */
        @NonNull
        public Builder setLongLived() {
            mIsLongLived = true;
            return this;
        }

        /**
         * "Rank" of a shortcut, which is a non-negative value that's used by the launcher app
         * to sort shortcuts.
@@ -1394,6 +1476,16 @@ public final class ShortcutInfo implements Parcelable {
        return mIntents;
    }

    /**
     * Return the Persons set with {@link Builder#setPersons(Person[])}.
     *
     * @hide
     */
    @Nullable
    public Person[] getPersons() {
        return clonePersons(mPersons);
    }

    /**
     * The extras in the intents.  We convert extras into {@link PersistableBundle} so we can
     * persist them.
@@ -1525,6 +1617,16 @@ public final class ShortcutInfo implements Parcelable {
        addFlags(FLAG_RETURNED_BY_SERVICE);
    }

    /** @hide */
    public boolean isLongLived() {
        return hasFlags(FLAG_LONG_LIVED);
    }

    /** @hide */
    public void setLongLived() {
        addFlags(FLAG_LONG_LIVED);
    }

    /** Return whether a shortcut is dynamic. */
    public boolean isDynamic() {
        return hasFlags(FLAG_DYNAMIC);
@@ -1893,6 +1995,8 @@ public final class ShortcutInfo implements Parcelable {
                mCategories.add(source.readString().intern());
            }
        }

        mPersons = source.readParcelableArray(cl, Person.class);
    }

    @Override
@@ -1940,6 +2044,8 @@ public final class ShortcutInfo implements Parcelable {
        } else {
            dest.writeInt(0);
        }

        dest.writeParcelableArray(mPersons, flags);
    }

    public static final Creator<ShortcutInfo> CREATOR =
@@ -2040,6 +2146,9 @@ public final class ShortcutInfo implements Parcelable {
        if (isReturnedByServer()) {
            sb.append("Rets");
        }
        if (isLongLived()) {
            sb.append("Liv");
        }
        sb.append("]");

        addIndentOrComma(sb, indent);
@@ -2094,6 +2203,11 @@ public final class ShortcutInfo implements Parcelable {

        addIndentOrComma(sb, indent);

        sb.append("persons=");
        sb.append(mPersons);

        addIndentOrComma(sb, indent);

        sb.append("icon=");
        sb.append(mIcon);

+9 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IUidObserver;
import android.app.Person;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -1587,6 +1588,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
        return intent;
    }

    /**
     * Make a Person.
     */
    protected Person makePerson(CharSequence name, String key, String uri) {
        final Person.Builder builder = new Person.Builder();
        return builder.setName(name).setKey(key).setUri(uri).build();
    }

    /**
     * Make an component name, with the client context.
     */
+29 −5
Original line number Diff line number Diff line
@@ -248,6 +248,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
                .setRank(123)
                .setPerson(makePerson("person", "personKey", "personUri"))
                .setLongLived()
                .setExtras(pb)
                .build();
        si.addFlags(ShortcutInfo.FLAG_PINNED);
@@ -267,9 +269,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals("action", si.getIntent().getAction());
        assertEquals("val", si.getIntent().getStringExtra("key"));
        assertEquals(123, si.getRank());
        assertEquals("person", si.getPersons()[0].getName());
        assertEquals("personKey", si.getPersons()[0].getKey());
        assertEquals("personUri", si.getPersons()[0].getUri());
        assertEquals(1, si.getExtras().getInt("k"));

        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
        assertEquals("abc", si.getBitmapPath());
        assertEquals(456, si.getIconResourceId());

@@ -345,6 +350,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
                .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
                .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
                .setRank(123)
                .setPerson(makePerson("person", "personKey", "personUri"))
                .setLongLived()
                .setExtras(pb)
                .build();
        sorig.addFlags(ShortcutInfo.FLAG_PINNED);
@@ -368,9 +375,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals("action", si.getIntent().getAction());
        assertEquals("val", si.getIntent().getStringExtra("key"));
        assertEquals(123, si.getRank());
        assertEquals("person", si.getPersons()[0].getName());
        assertEquals("personKey", si.getPersons()[0].getKey());
        assertEquals("personUri", si.getPersons()[0].getUri());
        assertEquals(1, si.getExtras().getInt("k"));

        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
        assertEquals("abc", si.getBitmapPath());
        assertEquals(456, si.getIconResourceId());
        assertEquals("string/r456", si.getIconResName());
@@ -388,9 +398,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals("action", si.getIntent().getAction());
        assertEquals("val", si.getIntent().getStringExtra("key"));
        assertEquals(123, si.getRank());
        assertEquals("person", si.getPersons()[0].getName());
        assertEquals("personKey", si.getPersons()[0].getKey());
        assertEquals("personUri", si.getPersons()[0].getUri());
        assertEquals(1, si.getExtras().getInt("k"));

        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
        assertEquals(null, si.getBitmapPath());

        assertEquals(456, si.getIconResourceId());
@@ -408,9 +421,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
        assertEquals(null, si.getIntent());
        assertEquals(123, si.getRank());
        assertEquals("person", si.getPersons()[0].getName());
        assertEquals("personKey", si.getPersons()[0].getKey());
        assertEquals("personUri", si.getPersons()[0].getUri());
        assertEquals(1, si.getExtras().getInt("k"));

        assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
        assertEquals(null, si.getBitmapPath());

        assertEquals(456, si.getIconResourceId());
@@ -428,9 +444,11 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals(null, si.getCategories());
        assertEquals(null, si.getIntent());
        assertEquals(0, si.getRank());
        assertEquals(null, si.getPersons());
        assertEquals(null, si.getExtras());

        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY
                | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
        assertEquals(null, si.getBitmapPath());

        assertEquals(456, si.getIconResourceId());
@@ -690,6 +708,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
        assertEquals("text", si.getText());
        assertEquals(set("x"), si.getCategories());

        si = sorig.clone(/* flags=*/ 0);
        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
                .setPerson(makePerson("person", "", "")).build());
        assertEquals("text", si.getText());
        assertEquals("person", si.getPersons()[0].getName());

        si = sorig.clone(/* flags=*/ 0);
        si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
                .setIntent(makeIntent("action2", ShortcutActivity.class)).build());