DO NOT MERGE Change batch finalization timeout mechanism from

Handler#sendMessageDelayed() to a wakeful alarm

Messages sent with Handler#sendMessageDelayed() didn't get delivered
until the device woke up after being idle, which resulted in
potentially very long windows of logs accumulation and highly possible
network log loss from before the device becaming idle.

Bug: 34157435
Test: manual with decreased timeout over a few timeout iterations
Change-Id: I22d9cc743acb1a478d2da5407c5718e7f95e89cb
This commit is contained in:
Michal Karpinski
2017-01-25 16:53:12 +00:00
parent a60f7151e6
commit 1710e5f079
2 changed files with 33 additions and 8 deletions

View File

@@ -1466,6 +1466,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
}
AlarmManager getAlarmManager() {
return (AlarmManager) mContext.getSystemService(AlarmManager.class);
}
IWindowManager getIWindowManager() {
return IWindowManager.Stub
.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
@@ -1985,7 +1989,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
long token = mInjector.binderClearCallingIdentity();
try {
int affectedUserHandle = parent ? getProfileParentId(userHandle) : userHandle;
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
AlarmManager am = mInjector.getAlarmManager();
PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,

View File

@@ -16,12 +16,15 @@
package com.android.server.devicepolicy;
import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.NetworkEvent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -42,11 +45,26 @@ final class NetworkLoggingHandler extends Handler {
// If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc
private static final int MAX_EVENTS_PER_BATCH = 1200;
private static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90);
private static final long BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS =
TimeUnit.MINUTES.toMillis(30);
static final int LOG_NETWORK_EVENT_MSG = 1;
static final int FINALIZE_BATCH_MSG = 2;
private static final String NETWORK_LOGGING_TIMEOUT_ALARM_TAG = "NetworkLogging.batchTimeout";
private final DevicePolicyManagerService mDpm;
private final AlarmManager mAlarmManager;
private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
@Override
public void onAlarm() {
Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+ mNetworkEvents.size() + " pending events.");
synchronized (NetworkLoggingHandler.this) {
finalizeBatchAndNotifyDeviceOwnerIfNotEmpty();
}
}
};
static final int LOG_NETWORK_EVENT_MSG = 1;
// threadsafe as it's Handler's thread confined
@GuardedBy("this")
@@ -62,6 +80,7 @@ final class NetworkLoggingHandler extends Handler {
NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
super(looper);
mDpm = dpm;
mAlarmManager = mDpm.mInjector.getAlarmManager();
}
@Override
@@ -77,17 +96,19 @@ final class NetworkLoggingHandler extends Handler {
}
break;
}
case FINALIZE_BATCH_MSG: {
finalizeBatchAndNotifyDeviceOwnerIfNotEmpty();
default: {
Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
break;
}
}
}
void scheduleBatchFinalization() {
removeMessages(FINALIZE_BATCH_MSG);
sendMessageDelayed(obtainMessage(FINALIZE_BATCH_MSG), BATCH_FINALIZATION_TIMEOUT_MS);
Log.d(TAG, "Scheduled new batch finalization " + BATCH_FINALIZATION_TIMEOUT_MS
final long when = SystemClock.elapsedRealtime() + BATCH_FINALIZATION_TIMEOUT_MS;
mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
mBatchTimeoutAlarmListener, this);
Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+ "ms from now.");
}