Loading services/core/java/com/android/server/pm/ShortcutPackage.java +7 −6 Original line number Diff line number Diff line Loading @@ -490,7 +490,7 @@ class ShortcutPackage extends ShortcutPackageItem { * <p>This takes care of the resetting the counter for foreground apps as well as after * locale changes. */ public int getApiCallCount() { public int getApiCallCount(boolean unlimited) { final ShortcutService s = mShortcutUser.mService; // Reset the counter if: Loading @@ -498,8 +498,9 @@ class ShortcutPackage extends ShortcutPackageItem { // - the package is *not* in foreground now, but was in foreground at some point // since the previous time it had been. if (s.isUidForegroundLocked(mPackageUid) || mLastKnownForegroundElapsedTime < s.getUidLastForegroundElapsedTimeLocked(mPackageUid)) { || (mLastKnownForegroundElapsedTime < s.getUidLastForegroundElapsedTimeLocked(mPackageUid)) || unlimited) { mLastKnownForegroundElapsedTime = s.injectElapsedRealtime(); resetRateLimiting(); } Loading Loading @@ -538,10 +539,10 @@ class ShortcutPackage extends ShortcutPackageItem { * <p>This takes care of the resetting the counter for foreground apps as well as after * locale changes, which is done internally by {@link #getApiCallCount}. */ public boolean tryApiCall() { public boolean tryApiCall(boolean unlimited) { final ShortcutService s = mShortcutUser.mService; if (getApiCallCount() >= s.mMaxUpdatesPerInterval) { if (getApiCallCount(unlimited) >= s.mMaxUpdatesPerInterval) { return false; } mApiCallCount++; Loading Loading @@ -1248,7 +1249,7 @@ class ShortcutPackage extends ShortcutPackageItem { pw.print(prefix); pw.print(" "); pw.print("Calls: "); pw.print(getApiCallCount()); pw.print(getApiCallCount(/*unlimited=*/ false)); pw.println(); // getApiCallCount() may have updated mLastKnownForegroundElapsedTime. Loading services/core/java/com/android/server/pm/ShortcutService.java +31 −4 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.pm; import android.Manifest.permission; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1726,6 +1727,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1738,7 +1742,7 @@ public class ShortcutService extends IShortcutService.Stub { ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } Loading Loading @@ -1777,6 +1781,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1790,7 +1797,7 @@ public class ShortcutService extends IShortcutService.Stub { ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } Loading Loading @@ -1859,6 +1866,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1875,7 +1885,7 @@ public class ShortcutService extends IShortcutService.Stub { assignImplicitRanks(newShortcuts); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } for (int i = 0; i < size; i++) { Loading Loading @@ -2144,11 +2154,14 @@ public class ShortcutService extends IShortcutService.Stub { public int getRemainingCallCount(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); return mMaxUpdatesPerInterval - ps.getApiCallCount(); return mMaxUpdatesPerInterval - ps.getApiCallCount(unlimited); } } Loading Loading @@ -2298,6 +2311,15 @@ public class ShortcutService extends IShortcutService.Stub { callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } /** * Returns true if the caller has the "UNLIMITED_SHORTCUTS_API_CALLS" permission. */ @VisibleForTesting boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) { return mContext.checkPermission(permission.UNLIMITED_SHORTCUTS_API_CALLS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } // This method is extracted so we can directly call this method from unit tests, // even when hasShortcutPermission() is overridden. @VisibleForTesting Loading Loading @@ -4197,6 +4219,11 @@ public class ShortcutService extends IShortcutService.Stub { return getCallingUid(); } @VisibleForTesting int injectBinderCallingPid() { return getCallingPid(); } private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +20 −1 Original line number Diff line number Diff line Loading @@ -288,6 +288,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mInjectedCallingUid; } @Override int injectBinderCallingPid() { // Note it's not used in tests, so just return a "random" value. return mInjectedCallingUid * 123; } @Override int injectGetPackageUid(String packageName, int userId) { return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid; Loading Loading @@ -324,6 +330,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mDefaultLauncherChecker.test(callingPackage, userId); } @Override boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) { return mInjectHasUnlimitedShortcutsApiCallsPermission; } @Override ComponentName getDefaultLauncher(@UserIdInt int userId) { final ComponentName activity = mDefaultLauncher.get(userId); Loading Loading @@ -518,6 +529,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mInjectedCallingUid; } @Override int injectBinderCallingPid() { // Note it's not used in tests, so just return a "random" value. return mInjectedCallingUid * 123; } @Override long injectClearCallingIdentity() { final int prevCallingUid = mInjectedCallingUid; Loading Loading @@ -705,6 +722,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected boolean mInjectCheckAccessShortcutsPermission = false; protected boolean mInjectHasUnlimitedShortcutsApiCallsPermission = false; static { QUERY_ALL.setQueryFlags( ShortcutQuery.FLAG_GET_ALL_KINDS); Loading Loading @@ -1207,7 +1226,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } /** * This controls {@link ShortcutService#hasShortcutHostPermission(String, int)}, but * This controls {@link ShortcutService#hasShortcutHostPermission}, but * not {@link ShortcutService#getDefaultLauncher(int)}. To control the later, use * {@link #setDefaultLauncher(int, ComponentName)}. */ Loading services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +32 −1 Original line number Diff line number Diff line Loading @@ -366,6 +366,37 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } public void testUnlimitedCalls() { setCaller(CALLING_PACKAGE_1, USER_0); final ShortcutInfo si1 = makeShortcut("shortcut1"); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.setDynamicShortcuts(list(si1))); assertEquals(2, mManager.getRemainingCallCount()); assertTrue(mManager.addDynamicShortcuts(list(si1))); assertEquals(1, mManager.getRemainingCallCount()); assertTrue(mManager.updateShortcuts(list(si1))); assertEquals(0, mManager.getRemainingCallCount()); // Unlimited now. mInjectHasUnlimitedShortcutsApiCallsPermission = true; assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.setDynamicShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.addDynamicShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.updateShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); } public void testPublishWithNoActivity() { // If activity is not explicitly set, use the default one. Loading Loading
services/core/java/com/android/server/pm/ShortcutPackage.java +7 −6 Original line number Diff line number Diff line Loading @@ -490,7 +490,7 @@ class ShortcutPackage extends ShortcutPackageItem { * <p>This takes care of the resetting the counter for foreground apps as well as after * locale changes. */ public int getApiCallCount() { public int getApiCallCount(boolean unlimited) { final ShortcutService s = mShortcutUser.mService; // Reset the counter if: Loading @@ -498,8 +498,9 @@ class ShortcutPackage extends ShortcutPackageItem { // - the package is *not* in foreground now, but was in foreground at some point // since the previous time it had been. if (s.isUidForegroundLocked(mPackageUid) || mLastKnownForegroundElapsedTime < s.getUidLastForegroundElapsedTimeLocked(mPackageUid)) { || (mLastKnownForegroundElapsedTime < s.getUidLastForegroundElapsedTimeLocked(mPackageUid)) || unlimited) { mLastKnownForegroundElapsedTime = s.injectElapsedRealtime(); resetRateLimiting(); } Loading Loading @@ -538,10 +539,10 @@ class ShortcutPackage extends ShortcutPackageItem { * <p>This takes care of the resetting the counter for foreground apps as well as after * locale changes, which is done internally by {@link #getApiCallCount}. */ public boolean tryApiCall() { public boolean tryApiCall(boolean unlimited) { final ShortcutService s = mShortcutUser.mService; if (getApiCallCount() >= s.mMaxUpdatesPerInterval) { if (getApiCallCount(unlimited) >= s.mMaxUpdatesPerInterval) { return false; } mApiCallCount++; Loading Loading @@ -1248,7 +1249,7 @@ class ShortcutPackage extends ShortcutPackageItem { pw.print(prefix); pw.print(" "); pw.print("Calls: "); pw.print(getApiCallCount()); pw.print(getApiCallCount(/*unlimited=*/ false)); pw.println(); // getApiCallCount() may have updated mLastKnownForegroundElapsedTime. Loading
services/core/java/com/android/server/pm/ShortcutService.java +31 −4 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.server.pm; import android.Manifest.permission; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -1726,6 +1727,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1738,7 +1742,7 @@ public class ShortcutService extends IShortcutService.Stub { ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } Loading Loading @@ -1777,6 +1781,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1790,7 +1797,7 @@ public class ShortcutService extends IShortcutService.Stub { ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } Loading Loading @@ -1859,6 +1866,9 @@ public class ShortcutService extends IShortcutService.Stub { final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); final int size = newShortcuts.size(); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); Loading @@ -1875,7 +1885,7 @@ public class ShortcutService extends IShortcutService.Stub { assignImplicitRanks(newShortcuts); // Throttling. if (!ps.tryApiCall()) { if (!ps.tryApiCall(unlimited)) { return false; } for (int i = 0; i < size; i++) { Loading Loading @@ -2144,11 +2154,14 @@ public class ShortcutService extends IShortcutService.Stub { public int getRemainingCallCount(String packageName, @UserIdInt int userId) { verifyCaller(packageName, userId); final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission( injectBinderCallingPid(), injectBinderCallingUid()); synchronized (mLock) { throwIfUserLockedL(userId); final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); return mMaxUpdatesPerInterval - ps.getApiCallCount(); return mMaxUpdatesPerInterval - ps.getApiCallCount(unlimited); } } Loading Loading @@ -2298,6 +2311,15 @@ public class ShortcutService extends IShortcutService.Stub { callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } /** * Returns true if the caller has the "UNLIMITED_SHORTCUTS_API_CALLS" permission. */ @VisibleForTesting boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) { return mContext.checkPermission(permission.UNLIMITED_SHORTCUTS_API_CALLS, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } // This method is extracted so we can directly call this method from unit tests, // even when hasShortcutPermission() is overridden. @VisibleForTesting Loading Loading @@ -4197,6 +4219,11 @@ public class ShortcutService extends IShortcutService.Stub { return getCallingUid(); } @VisibleForTesting int injectBinderCallingPid() { return getCallingPid(); } private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +20 −1 Original line number Diff line number Diff line Loading @@ -288,6 +288,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mInjectedCallingUid; } @Override int injectBinderCallingPid() { // Note it's not used in tests, so just return a "random" value. return mInjectedCallingUid * 123; } @Override int injectGetPackageUid(String packageName, int userId) { return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid; Loading Loading @@ -324,6 +330,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mDefaultLauncherChecker.test(callingPackage, userId); } @Override boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) { return mInjectHasUnlimitedShortcutsApiCallsPermission; } @Override ComponentName getDefaultLauncher(@UserIdInt int userId) { final ComponentName activity = mDefaultLauncher.get(userId); Loading Loading @@ -518,6 +529,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mInjectedCallingUid; } @Override int injectBinderCallingPid() { // Note it's not used in tests, so just return a "random" value. return mInjectedCallingUid * 123; } @Override long injectClearCallingIdentity() { final int prevCallingUid = mInjectedCallingUid; Loading Loading @@ -705,6 +722,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected boolean mInjectCheckAccessShortcutsPermission = false; protected boolean mInjectHasUnlimitedShortcutsApiCallsPermission = false; static { QUERY_ALL.setQueryFlags( ShortcutQuery.FLAG_GET_ALL_KINDS); Loading Loading @@ -1207,7 +1226,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } /** * This controls {@link ShortcutService#hasShortcutHostPermission(String, int)}, but * This controls {@link ShortcutService#hasShortcutHostPermission}, but * not {@link ShortcutService#getDefaultLauncher(int)}. To control the later, use * {@link #setDefaultLauncher(int, ComponentName)}. */ Loading
services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +32 −1 Original line number Diff line number Diff line Loading @@ -366,6 +366,37 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } public void testUnlimitedCalls() { setCaller(CALLING_PACKAGE_1, USER_0); final ShortcutInfo si1 = makeShortcut("shortcut1"); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.setDynamicShortcuts(list(si1))); assertEquals(2, mManager.getRemainingCallCount()); assertTrue(mManager.addDynamicShortcuts(list(si1))); assertEquals(1, mManager.getRemainingCallCount()); assertTrue(mManager.updateShortcuts(list(si1))); assertEquals(0, mManager.getRemainingCallCount()); // Unlimited now. mInjectHasUnlimitedShortcutsApiCallsPermission = true; assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.setDynamicShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.addDynamicShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); assertTrue(mManager.updateShortcuts(list(si1))); assertEquals(3, mManager.getRemainingCallCount()); } public void testPublishWithNoActivity() { // If activity is not explicitly set, use the default one. Loading