diff options
| author | 2018-02-21 11:24:43 -0800 | |
|---|---|---|
| committer | 2018-02-21 13:43:45 -0800 | |
| commit | 7d0fa81bae0d9d8595bb00dcbbd82df54c865c9f (patch) | |
| tree | 07933f1894d32fd065e766d618a34346e3f43585 | |
| parent | 2ebb02123122d6ef3b0cf5c115c2ea4e19319496 (diff) | |
Implement UNLIMITED_SHORTCUTS_API_CALLS permission.
Bug: 73083596
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest2 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest3 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest4 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest5 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest6 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest7 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest8 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest9 -w com.android.frameworks.servicestests
Test: adb shell am instrument -w -e class com.android.server.pm.ShortcutManagerTest10 -w com.android.frameworks.servicestests
Test: atest CtsShortcutManagerTestCases
Change-Id: I2283d105af166acc1a5b34921dd7a9cb50ef2e71
4 files changed, 90 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index e4c74edf0f0f..c11c0990fb12 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -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: @@ -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(); } @@ -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++; @@ -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. diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 034fd2390a8c..076f81f87340 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -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; @@ -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); @@ -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; } @@ -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); @@ -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; } @@ -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); @@ -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++) { @@ -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); } } @@ -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 @@ -4197,6 +4219,11 @@ public class ShortcutService extends IShortcutService.Stub { return getCallingUid(); } + @VisibleForTesting + int injectBinderCallingPid() { + return getCallingPid(); + } + private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 8cf575eec4d9..4ca1647ef415 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -289,6 +289,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @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; } @@ -325,6 +331,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override + boolean injectHasUnlimitedShortcutsApiCallsPermission(int callingPid, int callingUid) { + return mInjectHasUnlimitedShortcutsApiCallsPermission; + } + + @Override ComponentName getDefaultLauncher(@UserIdInt int userId) { final ComponentName activity = mDefaultLauncher.get(userId); if (activity != null) { @@ -519,6 +530,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @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; mInjectedCallingUid = Process.SYSTEM_UID; @@ -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); @@ -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)}. */ diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 857925b3ed17..845e05d28465 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -366,7 +366,38 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); } - public void testPublishWithNoActivity() { + 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. mRunningUsers.put(USER_10, true); |