diff options
6 files changed, 72 insertions, 27 deletions
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 360087c4dfe1..cbd5a6d54832 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -285,6 +285,27 @@ public class DeviceAdminReceiver extends BroadcastReceiver { = "android.app.action.NETWORK_LOGS_AVAILABLE"; /** + * A {@code long} containing a token of the current batch of network logs, that has to be used + * to retrieve the batch of logs by the device owner. + * + * @see #ACTION_NETWORK_LOGS_AVAILABLE + * @see DevicePolicyManager#retrieveNetworkLogs + * @hide + */ + public static final String EXTRA_NETWORK_LOGS_TOKEN = + "android.app.extra.EXTRA_NETWORK_LOGS_TOKEN"; + + /** + * An {@code int} count representing a total count of network logs inside the current batch of + * network logs. + * + * @see #ACTION_NETWORK_LOGS_AVAILABLE + * @hide + */ + public static final String EXTRA_NETWORK_LOGS_COUNT = + "android.app.extra.EXTRA_NETWORK_LOGS_COUNT"; + + /** * A string containing the SHA-256 hash of the bugreport file. * * @see #ACTION_BUGREPORT_SHARE @@ -644,19 +665,22 @@ public class DeviceAdminReceiver extends BroadcastReceiver { } /** - * Called when a new batch of network logs can be retrieved. This callback method will only ever - * be called when network logging is enabled. The logs can only be retrieved while network + * Called each time a new batch of network logs can be retrieved. This callback method will only + * ever be called when network logging is enabled. The logs can only be retrieved while network * logging is enabled. * * <p>This callback is only applicable to device owners. * * @param context The running context as per {@link #onReceive}. * @param intent The received intent as per {@link #onReceive}. + * @param batchToken The token representing the current batch of network logs. + * @param networkLogsCount The total count of events in the current batch of network logs. * @see DevicePolicyManager#retrieveNetworkLogs(ComponentName) * * @hide */ - public void onNetworkLogsAvailable(Context context, Intent intent) { + public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken, + int networkLogsCount) { } /** @@ -714,7 +738,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) { onSecurityLogsAvailable(context, intent); } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) { - onNetworkLogsAvailable(context, intent); + long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1); + int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0); + onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount); } } } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 0f72ae813421..c2197b55ef97 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6621,8 +6621,6 @@ public class DevicePolicyManager { * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param enabled whether network logging should be enabled or not. * @throws {@link SecurityException} if {@code admin} is not a device owner. - * @throws {@link RemoteException} if network logging could not be enabled or disabled due to - * the logging service not being available * @see #retrieveNetworkLogs * * @hide @@ -6655,7 +6653,10 @@ public class DevicePolicyManager { } /** - * Called by device owner to retrieve a new batch of network logging events. + * Called by device owner to retrieve the most recent batch of network logging events. + * A device owner has to provide a batchToken provided as part of + * {@link DeviceAdminReceiver#onNetworkLogsAvailable} callback. If the token doesn't match the + * token of the most recent available batch of logs, {@code null} will be returned. * * <p> {@link NetworkEvent} can be one of {@link DnsEvent} or {@link ConnectEvent}. * @@ -6666,16 +6667,20 @@ public class DevicePolicyManager { * {@link DeviceAdminReceiver#onNetworkLogsAvailable}. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param batchToken A token of the batch to retrieve * @return A new batch of network logs which is a list of {@link NetworkEvent}. Returns - * {@code null} if there's no batch currently awaiting for retrieval or if logging is disabled. + * {@code null} if the batch represented by batchToken is no longer available or if + * logging is disabled. * @throws {@link SecurityException} if {@code admin} is not a device owner. + * @see DeviceAdminReceiver#onNetworkLogsAvailable * * @hide */ - public List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin) { + public @Nullable List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin, + long batchToken) { throwIfParentInstance("retrieveNetworkLogs"); try { - return mService.retrieveNetworkLogs(admin); + return mService.retrieveNetworkLogs(admin, batchToken); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 3779bf398e0f..f0710ec269eb 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -315,5 +315,5 @@ interface IDevicePolicyManager { void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled); boolean isNetworkLoggingEnabled(in ComponentName admin); - List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin); + List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin, long batchToken); } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ad020b9bbde9..86b697fd7fce 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -488,9 +488,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * to listen for events. */ if (Intent.ACTION_USER_STARTED.equals(action) - && userHandle == mOwners.getDeviceOwnerUserId() - && isNetworkLoggingEnabledInternal()) { - setNetworkLoggingActiveInternal(true); + && userHandle == mOwners.getDeviceOwnerUserId()) { + synchronized (DevicePolicyManagerService.this) { + if (isNetworkLoggingEnabledInternalLocked()) { + setNetworkLoggingActiveInternal(true); + } + } } if (Intent.ACTION_BOOT_COMPLETED.equals(action) && userHandle == mOwners.getDeviceOwnerUserId() @@ -9433,7 +9436,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkNotNull(admin); ensureDeviceOwnerManagingSingleUser(admin); - if (enabled == isNetworkLoggingEnabledInternal()) { + if (enabled == isNetworkLoggingEnabledInternalLocked()) { // already in the requested state return; } @@ -9474,11 +9477,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Preconditions.checkNotNull(admin); synchronized (this) { getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); - return isNetworkLoggingEnabledInternal(); + return isNetworkLoggingEnabledInternalLocked(); } } - private synchronized boolean isNetworkLoggingEnabledInternal() { + private boolean isNetworkLoggingEnabledInternalLocked() { ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); return (deviceOwner != null) && deviceOwner.isNetworkLoggingEnabled; } @@ -9489,7 +9492,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Ideally this would be done with ParceledList, however it only supports homogeneous types. */ @Override - public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin) { + public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin, + long batchToken) { if (!mHasFeature) { return null; } @@ -9499,6 +9503,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mNetworkLogger == null) { return null; } - return isNetworkLoggingEnabledInternal() ? mNetworkLogger.retrieveLogs() : null; + return isNetworkLoggingEnabledInternalLocked() + ? mNetworkLogger.retrieveLogs(batchToken) + : null; } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java index 185ccc232aa9..8cb13da07c16 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java @@ -147,7 +147,7 @@ final class NetworkLogger { } } - List<NetworkEvent> retrieveLogs() { - return mNetworkLoggingHandler.retrieveFullLogBatch(); + List<NetworkEvent> retrieveLogs(long batchToken) { + return mNetworkLoggingHandler.retrieveFullLogBatch(batchToken); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java index 96884e6db711..98e5570a2f6b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java @@ -55,11 +55,15 @@ final class NetworkLoggingHandler extends Handler { private final DevicePolicyManagerService mDpm; // threadsafe as it's Handler's thread confined + @GuardedBy("this") private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<NetworkEvent>(); @GuardedBy("this") private ArrayList<NetworkEvent> mFullBatch; + @GuardedBy("this") + private long currentFullBatchToken; + NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) { super(looper); mDpm = dpm; @@ -97,17 +101,21 @@ final class NetworkLoggingHandler extends Handler { scheduleBatchFinalization(BATCH_FINALIZATION_TIMEOUT_MS); // notify DO that there's a new non-empty batch waiting if (mFullBatch.size() > 0) { - mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, - /* extras */ null); + currentFullBatchToken++; + Bundle extras = new Bundle(); + extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, currentFullBatchToken); + extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); + mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); } else { mFullBatch = null; } } - synchronized List<NetworkEvent> retrieveFullLogBatch() { - List<NetworkEvent> ret = mFullBatch; - mFullBatch = null; - return ret; + synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) { + if (batchToken != currentFullBatchToken) { + return null; + } + return mFullBatch; } } |