Retry SECURITY_LOGS_AVAILABLE if DO doesn't request the logs
Test: manually, with TestDPC. Bug: 34186771 Change-Id: I99ec406b05f7b072c2c729f6336d1a5cf0f7c3d4
This commit is contained in:
@@ -779,6 +779,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
|
||||
* become affiliated again (even if security logging is enabled).
|
||||
* See {@link DevicePolicyManager#setAffiliationIds}
|
||||
*
|
||||
* <p>This callback will be re-triggered if the logs are not retrieved.
|
||||
*
|
||||
* <p>This callback is only applicable to device owners.
|
||||
*
|
||||
* @param context The running context as per {@link #onReceive}.
|
||||
|
||||
@@ -68,6 +68,10 @@ class SecurityLogMonitor implements Runnable {
|
||||
* How often should Device Owner be notified under normal circumstances.
|
||||
*/
|
||||
private static final long RATE_LIMIT_INTERVAL_MILLISECONDS = TimeUnit.HOURS.toMillis(2);
|
||||
/**
|
||||
* How often to retry the notification about available logs if it is ignored or missed by DO.
|
||||
*/
|
||||
private static final long BROADCAST_RETRY_INTERVAL_MILLISECONDS = TimeUnit.MINUTES.toMillis(30);
|
||||
/**
|
||||
* Internally how often should the monitor poll the security logs from logd.
|
||||
*/
|
||||
@@ -82,7 +86,7 @@ class SecurityLogMonitor implements Runnable {
|
||||
|
||||
/**
|
||||
* When DO will be allowed to retrieve the log, in milliseconds since boot (as per
|
||||
* {@link SystemClock#elapsedRealtime()})
|
||||
* {@link SystemClock#elapsedRealtime()}). After that it will mark the time to retry broadcast.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private long mNextAllowedRetrievalTimeMillis = -1;
|
||||
@@ -256,36 +260,35 @@ class SecurityLogMonitor implements Runnable {
|
||||
}
|
||||
|
||||
private void notifyDeviceOwnerIfNeeded() throws InterruptedException {
|
||||
boolean shouldNotifyDO = false;
|
||||
boolean allowToRetrieveNow = false;
|
||||
boolean allowRetrievalAndNotifyDO = false;
|
||||
mLock.lockInterruptibly();
|
||||
try {
|
||||
if (mPaused) {
|
||||
return;
|
||||
}
|
||||
|
||||
// STOPSHIP(b/34186771): If the previous notification didn't reach the DO and logs were
|
||||
// not retrieved (e.g. the broadcast was sent before the user was unlocked), no more
|
||||
// subsequent callbacks will be sent. We should make sure that the DO gets notified
|
||||
// before logs are lost.
|
||||
int logSize = mPendingLogs.size();
|
||||
final int logSize = mPendingLogs.size();
|
||||
if (logSize >= BUFFER_ENTRIES_NOTIFICATION_LEVEL) {
|
||||
// Allow DO to retrieve logs if too many pending logs
|
||||
allowToRetrieveNow = true;
|
||||
if (DEBUG) Slog.d(TAG, "Number of log entries over threshold: " + logSize);
|
||||
} else if (logSize > 0) {
|
||||
if (SystemClock.elapsedRealtime() >= mNextAllowedRetrievalTimeMillis) {
|
||||
// Rate limit reset
|
||||
allowToRetrieveNow = true;
|
||||
if (DEBUG) Slog.d(TAG, "Timeout reached");
|
||||
if (!mAllowedToRetrieve) {
|
||||
allowRetrievalAndNotifyDO = true;
|
||||
}
|
||||
if (DEBUG) Slog.d(TAG, "Number of log entries over threshold: " + logSize);
|
||||
}
|
||||
if (logSize > 0 && SystemClock.elapsedRealtime() >= mNextAllowedRetrievalTimeMillis) {
|
||||
// Rate limit reset
|
||||
allowRetrievalAndNotifyDO = true;
|
||||
if (DEBUG) Slog.d(TAG, "Timeout reached");
|
||||
}
|
||||
if (allowRetrievalAndNotifyDO) {
|
||||
mAllowedToRetrieve = true;
|
||||
// Set the timeout to retry the notification if the DO misses it.
|
||||
mNextAllowedRetrievalTimeMillis = SystemClock.elapsedRealtime()
|
||||
+ BROADCAST_RETRY_INTERVAL_MILLISECONDS;
|
||||
}
|
||||
shouldNotifyDO = (!mAllowedToRetrieve) && allowToRetrieveNow;
|
||||
mAllowedToRetrieve = allowToRetrieveNow;
|
||||
} finally {
|
||||
mLock.unlock();
|
||||
}
|
||||
if (shouldNotifyDO) {
|
||||
if (allowRetrievalAndNotifyDO) {
|
||||
Slog.i(TAG, "notify DO");
|
||||
mService.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_SECURITY_LOGS_AVAILABLE,
|
||||
null);
|
||||
|
||||
Reference in New Issue
Block a user