summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Makoto Onuki <omakoto@google.com> 2018-02-21 11:24:43 -0800
committer Makoto Onuki <omakoto@google.com> 2018-02-21 13:43:45 -0800
commit7d0fa81bae0d9d8595bb00dcbbd82df54c865c9f (patch)
tree07933f1894d32fd065e766d618a34346e3f43585
parent2ebb02123122d6ef3b0cf5c115c2ea4e19319496 (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
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java13
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java35
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java33
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);