Throttler for incidentd based on size putting into dropbox.
The incidentd will accumulate the total size put into dropbox and once
it exceeds a threshold (currently 20MB) daily, it will stop further
requests. It allows collection again 24 hours later.
Bug: 64219725
Test: atest incidentd_test and manually flashed incidentd and test.
Change-Id: Iea21fbae40d5d01108797b190231d73e74eff213
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 9ae6240..28fb38a 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define DEBUG false
#include "Log.h"
#include "IncidentService.h"
@@ -38,9 +39,11 @@
enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
-//#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL * 60 * 5)
#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
+#define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024) // 20MB
+#define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000) // 1 Day
+
// ================================================================================
String16 const DUMP_PERMISSION("android.permission.DUMP");
String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
@@ -113,8 +116,12 @@
}
// ================================================================================
-ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue)
- : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS), mHandlerLooper(handlerLooper), mQueue(queue) {}
+ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
+ const sp<Throttler>& throttler)
+ : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
+ mHandlerLooper(handlerLooper),
+ mQueue(queue),
+ mThrottler(throttler) {}
ReportHandler::~ReportHandler() {}
@@ -159,10 +166,17 @@
reporter->batch.add(request);
}
+ if (mThrottler->shouldThrottle()) {
+ ALOGW("RunReport got throttled.");
+ return;
+ }
+
// Take the report, which might take a while. More requests might queue
// up while we're doing this, and we'll handle them in their next batch.
// TODO: We should further rate-limit the reports to no more than N per time-period.
- Reporter::run_report_status_t reportStatus = reporter->runReport();
+ size_t reportByteSize = 0;
+ Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
+ mThrottler->addReportSize(reportByteSize);
if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
unique_lock<mutex> lock(mLock);
schedule_send_backlog_to_dropbox_locked();
@@ -184,8 +198,9 @@
// ================================================================================
IncidentService::IncidentService(const sp<Looper>& handlerLooper)
- : mQueue(new ReportRequestQueue()) {
- mHandler = new ReportHandler(handlerLooper, mQueue);
+ : mQueue(new ReportRequestQueue()),
+ mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
+ mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
}
IncidentService::~IncidentService() {}
@@ -294,6 +309,10 @@
if (!args[0].compare(String8("privacy"))) {
return cmd_privacy(in, out, err, args);
}
+ if (!args[0].compare(String8("throttler"))) {
+ mThrottler->dump(out);
+ return NO_ERROR;
+ }
}
return cmd_help(out);
}
@@ -302,6 +321,9 @@
fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n");
fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n");
fprintf(out, " Prints/parses for the section id.\n");
+ fprintf(out, "\n");
+ fprintf(out, "usage: adb shell cmd incident throttler\n");
+ fprintf(out, " Prints the current throttler state\n");
return NO_ERROR;
}