diff options
author | Adnan Begovic <adnan@cyngn.com> | 2016-05-23 16:06:10 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2016-05-27 10:19:55 -0700 |
commit | b4088dd11909e3b19519520a8838251902446f9a (patch) | |
tree | 385cdbd332e8cd09b9e5e7a01097789b343b4cdf /services/core | |
parent | 8e897a5cb06c665fdb4a994bd9f13d0682ef4500 (diff) | |
download | frameworks_base-b4088dd11909e3b19519520a8838251902446f9a.zip frameworks_base-b4088dd11909e3b19519520a8838251902446f9a.tar.gz frameworks_base-b4088dd11909e3b19519520a8838251902446f9a.tar.bz2 |
appops: Implement concept of delayedcount.
High frequency request ops will be delayed until their ignore count
ceiling is met. This is to mitigate the overloading the main activity
manager service handler and having watchdog kill our service.
Google play services likes to share its uid with numerous packages to avoid
having to grant permissions from the users perspective and thus is the worst
example of overloading this queue -- so, to not encourage bad behavior,
we move them to the back of the line. NOTE: these values are magic, and may need
tuning. Ideally we'd want a ringbuffer or token bucket here to do proper rate
limiting.
Change-Id: I5c3e88807abc80f9700dd68dcecd87dac4626de7
TICKET: CYNGNOS-2869
Diffstat (limited to 'services/core')
-rw-r--r-- | services/core/java/com/android/server/AppOpsPolicy.java | 7 | ||||
-rw-r--r-- | services/core/java/com/android/server/AppOpsService.java | 42 |
2 files changed, 46 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/AppOpsPolicy.java b/services/core/java/com/android/server/AppOpsPolicy.java index 75bca05..d51983f 100644 --- a/services/core/java/com/android/server/AppOpsPolicy.java +++ b/services/core/java/com/android/server/AppOpsPolicy.java @@ -60,6 +60,11 @@ public class AppOpsPolicy { public static final int CONTROL_UNKNOWN = 2; + // Rate limiting thresholds for ask operations + public static final int RATE_LIMIT_OP_COUNT = 3; + public static final int RATE_LIMIT_OPS_TOTAL_PKG_COUNT = 4; + public static final int RATE_LIMIT_OP_DELAY_CEILING = 10; + public static int stringToControl(String show) { if ("true".equalsIgnoreCase(show)) { return CONTROL_SHOW; @@ -438,4 +443,4 @@ public class AppOpsPolicy { Slog.d(TAG, "Returning mode=" + mode); return mode; } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 83a0a99..b99e4db 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -184,6 +184,7 @@ public class AppOpsService extends IAppOpsService.Stub { final ArrayList<IBinder> clientTokens; public int allowedCount; public int ignoredCount; + public int delayedCount; public Op(int _uid, String _packageName, int _op, int _mode) { uid = _uid; @@ -1058,8 +1059,45 @@ public class AppOpsService extends IAppOpsService.Stub { + packageName + ")"); return switchOp.mode; } - op.noteOpCount++; - req = askOperationLocked(code, uid, packageName, switchOp); + + if (DEBUG) { + Log.d(TAG, "Package " + op.packageName + " has " + op.noteOpCount + + " requests and " + op.startOpCount + " start requests with " + + op.ignoredCount + " ignored at " + op.time + + " with a duration of " + + op.duration + " while being delayed " + op.delayedCount + + " times"); + Log.d(TAG, "Total pkops for " + ops.packageName + " " + + ops.uidState.pkgOps.size()); + } + + // First check what the global pkg ops count for the package, + // then check op scoped count. High frequency request ops will be delayed until + // their delay count ceiling is met. This is to mitigate the overloading the + // main activity manager service handler and having watchdog kill our service. + // Google play services likes to share its uid with numerous packages to avoid + // having to grant permissions from the users perspective and thus is the worst + // example of overloading this queue -- so, to not encourage bad behavior, + // we move them to the back of the line. NOTE: these values are magic, and may need + // tuning. Ideally we'd want a ringbuffer or token bucket here to do proper rate + // limiting. + if (ops.uidState.pkgOps.size() < AppOpsPolicy.RATE_LIMIT_OPS_TOTAL_PKG_COUNT + && op.noteOpCount < AppOpsPolicy.RATE_LIMIT_OP_COUNT + || op.delayedCount > AppOpsPolicy.RATE_LIMIT_OP_DELAY_CEILING) { + + // Reset delayed count, most ops will never need this + if (op.delayedCount > 0) { + if (DEBUG) Log.d(TAG, "Resetting delayed count for " + op.packageName); + op.delayedCount = 0; + } + + op.noteOpCount++; + req = askOperationLocked(code, uid, packageName, switchOp); + } else { + op.delayedCount++; + op.ignoredCount++; + return AppOpsManager.MODE_IGNORED; + } } } |