[DPM] Improvements to the network logs batch finalization mechanism

am: 4da4a5d0c8

Change-Id: I6318392173aeb2653734537569d03158799a099c
This commit is contained in:
Michal Karpinski
2017-01-13 09:51:27 +00:00
committed by android-build-merger
2 changed files with 21 additions and 22 deletions

View File

@@ -23,7 +23,6 @@ import android.content.pm.PackageManagerInternal;
import android.net.IIpConnectivityMetrics; import android.net.IIpConnectivityMetrics;
import android.net.INetdEventCallback; import android.net.INetdEventCallback;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.Process; import android.os.Process;
import android.os.RemoteException; import android.os.RemoteException;
@@ -115,8 +114,7 @@ final class NetworkLogger {
mHandlerThread.start(); mHandlerThread.start();
mNetworkLoggingHandler = new NetworkLoggingHandler(mHandlerThread.getLooper(), mNetworkLoggingHandler = new NetworkLoggingHandler(mHandlerThread.getLooper(),
mDpm); mDpm);
mNetworkLoggingHandler.scheduleBatchFinalization( mNetworkLoggingHandler.scheduleBatchFinalization();
NetworkLoggingHandler.BATCH_FINALIZATION_TIMEOUT_MS);
mIsLoggingEnabled.set(true); mIsLoggingEnabled.set(true);
return true; return true;
} else { } else {

View File

@@ -17,16 +17,11 @@
package com.android.server.devicepolicy; package com.android.server.devicepolicy;
import android.app.admin.DeviceAdminReceiver; import android.app.admin.DeviceAdminReceiver;
import android.app.admin.ConnectEvent;
import android.app.admin.DnsEvent;
import android.app.admin.NetworkEvent; import android.app.admin.NetworkEvent;
import android.net.IIpConnectivityMetrics;
import android.net.INetdEventCallback;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
@@ -44,10 +39,9 @@ final class NetworkLoggingHandler extends Handler {
static final String NETWORK_EVENT_KEY = "network_event"; static final String NETWORK_EVENT_KEY = "network_event";
// est. ~128kB of memory usage per full batch TODO(mkarpinski): fine tune based on testing data
// If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc // If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc
private static final int MAX_EVENTS_PER_BATCH = 1200; private static final int MAX_EVENTS_PER_BATCH = 1200;
static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90); private static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90);
static final int LOG_NETWORK_EVENT_MSG = 1; static final int LOG_NETWORK_EVENT_MSG = 1;
static final int FINALIZE_BATCH_MSG = 2; static final int FINALIZE_BATCH_MSG = 2;
@@ -78,31 +72,32 @@ final class NetworkLoggingHandler extends Handler {
if (networkEvent != null) { if (networkEvent != null) {
mNetworkEvents.add(networkEvent); mNetworkEvents.add(networkEvent);
if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) { if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
finalizeBatchAndNotifyDeviceOwner(); finalizeBatchAndNotifyDeviceOwnerIfNotEmpty();
} }
} }
break; break;
} }
case FINALIZE_BATCH_MSG: { case FINALIZE_BATCH_MSG: {
finalizeBatchAndNotifyDeviceOwner(); finalizeBatchAndNotifyDeviceOwnerIfNotEmpty();
break; break;
} }
} }
} }
void scheduleBatchFinalization(long delay) { void scheduleBatchFinalization() {
removeMessages(FINALIZE_BATCH_MSG); removeMessages(FINALIZE_BATCH_MSG);
sendMessageDelayed(obtainMessage(FINALIZE_BATCH_MSG), delay); sendMessageDelayed(obtainMessage(FINALIZE_BATCH_MSG), BATCH_FINALIZATION_TIMEOUT_MS);
Log.d(TAG, "Scheduled new batch finalization " + BATCH_FINALIZATION_TIMEOUT_MS
+ "ms from now.");
} }
private synchronized void finalizeBatchAndNotifyDeviceOwner() { private synchronized void finalizeBatchAndNotifyDeviceOwnerIfNotEmpty() {
mFullBatch = mNetworkEvents; if (mNetworkEvents.size() > 0) {
// start a new batch from scratch // finalize the batch and start a new one from scratch
mNetworkEvents = new ArrayList<NetworkEvent>(); mFullBatch = mNetworkEvents;
scheduleBatchFinalization(BATCH_FINALIZATION_TIMEOUT_MS);
// notify DO that there's a new non-empty batch waiting
if (mFullBatch.size() > 0) {
mCurrentFullBatchToken++; mCurrentFullBatchToken++;
mNetworkEvents = new ArrayList<NetworkEvent>();
// notify DO that there's a new non-empty batch waiting
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken);
extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size());
@@ -110,8 +105,14 @@ final class NetworkLoggingHandler extends Handler {
+ mCurrentFullBatchToken); + mCurrentFullBatchToken);
mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
} else { } else {
mFullBatch = null; // don't notify the DO, since there are no events; DPC can still retrieve
// the last full batch
Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+ " the DPC, the batchToken of last available batch: "
+ mCurrentFullBatchToken);
} }
// regardless of whether the batch was non-empty schedule a new finalization after timeout
scheduleBatchFinalization();
} }
synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) { synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) {