Loading core/java/android/content/pm/ShortcutInfo.java +18 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.TaskStackBuilder; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; Loading Loading @@ -95,6 +94,9 @@ public final class ShortcutInfo implements Parcelable { /** @hide */ public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9; /** @hide */ public static final int FLAG_RETURNED_BY_SERVICE = 1 << 10; /** @hide */ @IntDef(flag = true, value = { Loading @@ -108,6 +110,7 @@ public final class ShortcutInfo implements Parcelable { FLAG_STRINGS_RESOLVED, FLAG_IMMUTABLE, FLAG_ADAPTIVE_BITMAP, FLAG_RETURNED_BY_SERVICE }) @Retention(RetentionPolicy.SOURCE) public @interface ShortcutFlags {} Loading Loading @@ -1343,6 +1346,16 @@ public final class ShortcutInfo implements Parcelable { return (mFlags & flags) == flags; } /** @hide */ public boolean isReturnedByServer() { return hasFlags(FLAG_RETURNED_BY_SERVICE); } /** @hide */ public void setReturnedByServer() { addFlags(FLAG_RETURNED_BY_SERVICE); } /** Return whether a shortcut is dynamic. */ public boolean isDynamic() { return hasFlags(FLAG_DYNAMIC); Loading Loading @@ -1450,7 +1463,7 @@ public final class ShortcutInfo implements Parcelable { /** * Return whether a shortcut's icon is adaptive bitmap following design guideline * defined in {@link AdaptiveIconDrawable}. * defined in {@link android.graphics.drawable.AdaptiveIconDrawable}. * * @hide internal/unit tests only */ Loading Loading @@ -1776,6 +1789,9 @@ public final class ShortcutInfo implements Parcelable { if (hasStringResourcesResolved()) { sb.append("Sr"); } if (isReturnedByServer()) { sb.append("V"); } sb.append("]"); sb.append(", packageName="); Loading core/java/android/content/pm/ShortcutManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -618,6 +618,10 @@ public class ShortcutManager { /** * Return all dynamic shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading @@ -633,6 +637,10 @@ public class ShortcutManager { /** * Return all static (manifest) shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading Loading @@ -697,6 +705,10 @@ public class ShortcutManager { /** * Return all pinned shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading services/core/java/com/android/server/pm/ShortcutService.java +14 −2 Original line number Diff line number Diff line Loading @@ -1611,6 +1611,11 @@ public class ShortcutService extends IShortcutService.Stub { */ private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate, boolean forPinRequest) { if (shortcut.isReturnedByServer()) { Log.w(TAG, "Re-publishing ShortcutInfo returned by server is not supported." + " Some information such as icon may lost from shortcut."); } Preconditions.checkNotNull(shortcut, "Null shortcut detected"); if (shortcut.getActivity() != null) { Preconditions.checkState( Loading Loading @@ -1670,6 +1675,13 @@ public class ShortcutService extends IShortcutService.Stub { } } private List<ShortcutInfo> setReturnedByServer(List<ShortcutInfo> shortcuts) { for (int i = shortcuts.size() - 1; i >= 0; i--) { shortcuts.get(i).setReturnedByServer(); } return shortcuts; } // === APIs === @Override Loading Loading @@ -2049,7 +2061,7 @@ public class ShortcutService extends IShortcutService.Stub { final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); ps.findAll(ret, query, cloneFlags); return new ParceledListSlice<>(ret); return new ParceledListSlice<>(setReturnedByServer(ret)); } @Override Loading Loading @@ -2406,7 +2418,7 @@ public class ShortcutService extends IShortcutService.Stub { }); } } return ret; return setReturnedByServer(ret); } private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage, Loading services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +46 −0 Original line number Diff line number Diff line Loading @@ -7399,4 +7399,50 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { "s21", "s22"); }); } public void testReturnedByServer() { // Package 1 updated, with manifest shortcuts. addManifestShortcutResource( new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(mManager.getManifestShortcuts()) .haveIds("ms1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1")))); assertWith(mManager.getDynamicShortcuts()) .haveIds("s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); // Pin them. runWithCaller(LAUNCHER_1, USER_0, () -> { mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1", "s1"), getCallingUser()); assertWith(getShortcutAsLauncher(USER_0)) .haveIds("ms1", "s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(mManager.getPinnedShortcuts()) .haveIds("ms1", "s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { // This shows a warning log, but should still work. assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts())); assertWith(mManager.getDynamicShortcuts()) .haveIds("s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); } } Loading
core/java/android/content/pm/ShortcutInfo.java +18 −2 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.TaskStackBuilder; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherApps.ShortcutQuery; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; Loading Loading @@ -95,6 +94,9 @@ public final class ShortcutInfo implements Parcelable { /** @hide */ public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9; /** @hide */ public static final int FLAG_RETURNED_BY_SERVICE = 1 << 10; /** @hide */ @IntDef(flag = true, value = { Loading @@ -108,6 +110,7 @@ public final class ShortcutInfo implements Parcelable { FLAG_STRINGS_RESOLVED, FLAG_IMMUTABLE, FLAG_ADAPTIVE_BITMAP, FLAG_RETURNED_BY_SERVICE }) @Retention(RetentionPolicy.SOURCE) public @interface ShortcutFlags {} Loading Loading @@ -1343,6 +1346,16 @@ public final class ShortcutInfo implements Parcelable { return (mFlags & flags) == flags; } /** @hide */ public boolean isReturnedByServer() { return hasFlags(FLAG_RETURNED_BY_SERVICE); } /** @hide */ public void setReturnedByServer() { addFlags(FLAG_RETURNED_BY_SERVICE); } /** Return whether a shortcut is dynamic. */ public boolean isDynamic() { return hasFlags(FLAG_DYNAMIC); Loading Loading @@ -1450,7 +1463,7 @@ public final class ShortcutInfo implements Parcelable { /** * Return whether a shortcut's icon is adaptive bitmap following design guideline * defined in {@link AdaptiveIconDrawable}. * defined in {@link android.graphics.drawable.AdaptiveIconDrawable}. * * @hide internal/unit tests only */ Loading Loading @@ -1776,6 +1789,9 @@ public final class ShortcutInfo implements Parcelable { if (hasStringResourcesResolved()) { sb.append("Sr"); } if (isReturnedByServer()) { sb.append("V"); } sb.append("]"); sb.append(", packageName="); Loading
core/java/android/content/pm/ShortcutManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -618,6 +618,10 @@ public class ShortcutManager { /** * Return all dynamic shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading @@ -633,6 +637,10 @@ public class ShortcutManager { /** * Return all static (manifest) shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading Loading @@ -697,6 +705,10 @@ public class ShortcutManager { /** * Return all pinned shortcuts from the caller app. * * <p>This API is intended to be used for examining what shortcuts are currently published. * Re-publishing returned {@link ShortcutInfo}s via APIs such as * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons. * * @throws IllegalStateException when the user is locked. */ @NonNull Loading
services/core/java/com/android/server/pm/ShortcutService.java +14 −2 Original line number Diff line number Diff line Loading @@ -1611,6 +1611,11 @@ public class ShortcutService extends IShortcutService.Stub { */ private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate, boolean forPinRequest) { if (shortcut.isReturnedByServer()) { Log.w(TAG, "Re-publishing ShortcutInfo returned by server is not supported." + " Some information such as icon may lost from shortcut."); } Preconditions.checkNotNull(shortcut, "Null shortcut detected"); if (shortcut.getActivity() != null) { Preconditions.checkState( Loading Loading @@ -1670,6 +1675,13 @@ public class ShortcutService extends IShortcutService.Stub { } } private List<ShortcutInfo> setReturnedByServer(List<ShortcutInfo> shortcuts) { for (int i = shortcuts.size() - 1; i >= 0; i--) { shortcuts.get(i).setReturnedByServer(); } return shortcuts; } // === APIs === @Override Loading Loading @@ -2049,7 +2061,7 @@ public class ShortcutService extends IShortcutService.Stub { final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); ps.findAll(ret, query, cloneFlags); return new ParceledListSlice<>(ret); return new ParceledListSlice<>(setReturnedByServer(ret)); } @Override Loading Loading @@ -2406,7 +2418,7 @@ public class ShortcutService extends IShortcutService.Stub { }); } } return ret; return setReturnedByServer(ret); } private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage, Loading
services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +46 −0 Original line number Diff line number Diff line Loading @@ -7399,4 +7399,50 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { "s21", "s22"); }); } public void testReturnedByServer() { // Package 1 updated, with manifest shortcuts. addManifestShortcutResource( new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()), R.xml.shortcut_1); updatePackageVersion(CALLING_PACKAGE_1, 1); mService.mPackageMonitor.onReceive(getTestContext(), genPackageAddIntent(CALLING_PACKAGE_1, USER_0)); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(mManager.getManifestShortcuts()) .haveIds("ms1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1")))); assertWith(mManager.getDynamicShortcuts()) .haveIds("s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); // Pin them. runWithCaller(LAUNCHER_1, USER_0, () -> { mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1", "s1"), getCallingUser()); assertWith(getShortcutAsLauncher(USER_0)) .haveIds("ms1", "s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertWith(mManager.getPinnedShortcuts()) .haveIds("ms1", "s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { // This shows a warning log, but should still work. assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts())); assertWith(mManager.getDynamicShortcuts()) .haveIds("s1") .forAllShortcuts(si -> assertTrue(si.isReturnedByServer())); }); } }