Loading core/java/android/app/admin/DeviceAdminReceiver.java +10 −1 Original line number Diff line number Diff line Loading @@ -768,6 +768,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { /** * Called when a new batch of security logs can be retrieved. * * <p>If a secondary user or profile is created, this callback won't be received until all users * become affiliated again (even if security logging is enabled). * See {@link DevicePolicyManager#setAffiliationIds} * * <p>This callback is only applicable to device owners. * * @param context The running context as per {@link #onReceive}. Loading @@ -782,13 +786,18 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * ever be called when network logging is enabled. The logs can only be retrieved while network * logging is enabled. * * <p>If a secondary user or profile is created, this callback won't be received until all users * become affiliated again (even if network logging is enabled). It will also no longer be * possible to retrieve the network logs batch with the most recent {@code batchToken} provided * by this callback. See {@link DevicePolicyManager#setAffiliationIds}. * * <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) * @see DevicePolicyManager#retrieveNetworkLogs */ public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken, int networkLogsCount) { Loading core/java/android/app/admin/DevicePolicyManager.java +47 −21 Original line number Diff line number Diff line Loading @@ -3651,15 +3651,16 @@ public class DevicePolicyManager { /** * Called by a device owner to request a bugreport. * <p> * There must be only one user on the device, managed by the device owner. Otherwise a * {@link SecurityException} will be thrown. * If the device contains secondary users or profiles, they must be affiliated with the device * owner user. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds}. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @return {@code true} if the bugreport collection started successfully, or {@code false} if it * wasn't triggered because a previous bugreport operation is still active (either the * bugreport is still running or waiting for the user to share or decline) * @throws SecurityException if {@code admin} is not a device owner, or if there are users other * than the one managed by the device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. */ public boolean requestBugreport(@NonNull ComponentName admin) { throwIfParentInstance("requestBugreport"); Loading Loading @@ -6631,14 +6632,16 @@ public class DevicePolicyManager { } /** * Called by device owner to control the security logging feature. Logging can only be * enabled on single user devices where the sole user is managed by the device owner. * Called by device owner to control the security logging feature. * * <p> Security logs contain various information intended for security auditing purposes. * See {@link SecurityEvent} for details. * * <p>There must be only one user on the device, managed by the device owner. * Otherwise a {@link SecurityException} will be thrown. * <p><strong>Note:</strong> The device owner won't be able to retrieve security logs if there * are unaffiliated secondary users or profiles on the device, regardless of whether the * feature is enabled. Logs will be discarded if the internal buffer fills up while waiting for * all users to become affiliated. Therefore it's recommended that affiliation ids are set for * new users as soon as possible after provisioning via {@link #setAffiliationIds}. * * @param admin Which device owner this request is associated with. * @param enabled whether security logging should be enabled or not. Loading Loading @@ -6680,13 +6683,16 @@ public class DevicePolicyManager { * <p> Access to the logs is rate limited and it will only return new logs after the device * owner has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}. * * <p>There must be only one user on the device, managed by the device owner. * Otherwise a {@link SecurityException} will be thrown. * <p>If there is any other user or profile on the device, it must be affiliated with the * device owner. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds} * * @param admin Which device owner this request is associated with. * @return the new batch of security logs which is a list of {@link SecurityEvent}, * or {@code null} if rate limitation is exceeded or if logging is currently disabled. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see DeviceAdminReceiver#onSecurityLogsAvailable */ public @Nullable List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) { throwIfParentInstance("retrieveSecurityLogs"); Loading Loading @@ -6726,14 +6732,17 @@ public class DevicePolicyManager { * will result in {@code null} being returned. The device logs are retrieved from a RAM region * which is not guaranteed to be corruption-free during power cycles, as a result be cautious * about data corruption when parsing. </strong> * <p> * There must be only one user on the device, managed by the device owner. Otherwise a * {@link SecurityException} will be thrown. * * <p>If there is any other user or profile on the device, it must be affiliated with the * device owner. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds} * * @param admin Which device owner this request is associated with. * @return Device logs from before the latest reboot of the system, or {@code null} if this API * is not supported on the device. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see #retrieveSecurityLogs */ public @Nullable List<SecurityEvent> retrievePreRebootSecurityLogs( @NonNull ComponentName admin) { Loading Loading @@ -6939,6 +6948,12 @@ public class DevicePolicyManager { * Indicates the entity that controls the device or profile owner. Two users/profiles are * affiliated if the set of ids set by their device or profile owners intersect. * * <p><strong>Note:</strong> Features that depend on user affiliation (such as security logging * or {@link #bindDeviceAdminServiceAsUser}) won't be available when a secondary user or profile * is created, until it becomes affiliated. Therefore it is recommended that the appropriate * affiliation ids are set by its profile owner as soon as possible after the user/profile is * created. * * @param admin Which profile or device owner this request is associated with. * @param ids A list of opaque non-empty affiliation ids. Duplicate elements will be ignored. * Loading Loading @@ -7138,15 +7153,19 @@ public class DevicePolicyManager { } /** * Called by a device owner to control the network logging feature. Logging can only be * enabled on single user devices where the sole user is managed by the device owner. If a new * user is added on the device, logging is disabled. * Called by a device owner to control the network logging feature. * * <p> Network logs contain DNS lookup and connect() library call events. * * <p><strong>Note:</strong> The device owner won't be able to retrieve network logs if there * are unaffiliated secondary users or profiles on the device, regardless of whether the * feature is enabled. Logs will be discarded if the internal buffer fills up while waiting for * all users to become affiliated. Therefore it's recommended that affiliation ids are set for * new users as soon as possible after provisioning via {@link #setAffiliationIds}. * * @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 SecurityException if {@code admin} is not a device owner. * @see #retrieveNetworkLogs */ public void setNetworkLoggingEnabled(@NonNull ComponentName admin, boolean enabled) { Loading @@ -7164,7 +7183,7 @@ public class DevicePolicyManager { * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Can only * be {@code null} if the caller has MANAGE_USERS permission. * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise. * @throws {@link SecurityException} if {@code admin} is not a device owner and caller has * @throws SecurityException if {@code admin} is not a device owner and caller has * no MANAGE_USERS permission */ public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) { Loading @@ -7190,12 +7209,19 @@ public class DevicePolicyManager { * after the device device owner has been notified via * {@link DeviceAdminReceiver#onNetworkLogsAvailable}. * * <p>If a secondary user or profile is created, calling this method will throw a * {@link SecurityException} until all users become affiliated again. It will also no longer be * possible to retrieve the network logs batch with the most recent batchToken provided * by {@link DeviceAdminReceiver#onNetworkLogsAvailable}. See * {@link DevicePolicyManager#setAffiliationIds}. * * @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 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. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see DeviceAdminReceiver#onNetworkLogsAvailable */ public @Nullable List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin, Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +175 −122 File changed.Preview size limit exceeded, changes collapsed. Show changes services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java +38 −3 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.util.Slog; import com.android.server.ServiceThread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -130,6 +129,8 @@ final class NetworkLogger { Log.d(TAG, "Stopping network logging"); // stop the logging regardless of whether we fail to unregister listener mIsLoggingEnabled.set(false); discardLogs(); try { if (!checkIpConnectivityMetricsService()) { // the IIpConnectivityMetrics service should have been present at this point Loading @@ -140,9 +141,43 @@ final class NetworkLogger { return mIpConnectivityMetrics.unregisterNetdEventCallback(); } catch (RemoteException re) { Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re); return true; } finally { if (mHandlerThread != null) { mHandlerThread.quitSafely(); return true; } } } /** * If logs are being collected, keep collecting them but stop notifying the device owner that * new logs are available (since they cannot be retrieved) */ void pause() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.pause(); } } /** * If logs are being collected, start notifying the device owner when logs are ready to be * collected again (if it was paused). * <p>If logging is enabled and there are logs ready to be retrieved, this method will attempt * to notify the device owner. Therefore calling identity should be cleared before calling it * (in case the method is called from a user other than the DO's user). */ void resume() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.resume(); } } /** * Discard all collected logs. */ void discardLogs() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.discardLogs(); } } Loading services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +62 −14 Original line number Diff line number Diff line Loading @@ -55,10 +55,16 @@ final class NetworkLoggingHandler extends Handler { @GuardedBy("this") private ArrayList<NetworkEvent> mFullBatch; // each full batch is represented by its token, which the DPC has to provide back to revieve it @GuardedBy("this") private boolean mPaused = false; // each full batch is represented by its token, which the DPC has to provide back to retrieve it @GuardedBy("this") private long mCurrentFullBatchToken; @GuardedBy("this") private long mLastRetrievedFullBatchToken; NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) { super(looper); mDpm = dpm; Loading @@ -70,15 +76,19 @@ final class NetworkLoggingHandler extends Handler { case LOG_NETWORK_EVENT_MSG: { NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); if (networkEvent != null) { synchronized (NetworkLoggingHandler.this) { mNetworkEvents.add(networkEvent); if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) { finalizeBatchAndNotifyDeviceOwnerIfNotEmpty(); finalizeBatchAndNotifyDeviceOwnerLocked(); } } } break; } case FINALIZE_BATCH_MSG: { finalizeBatchAndNotifyDeviceOwnerIfNotEmpty(); synchronized (NetworkLoggingHandler.this) { finalizeBatchAndNotifyDeviceOwnerLocked(); } break; } } Loading @@ -91,22 +101,49 @@ final class NetworkLoggingHandler extends Handler { + "ms from now."); } private synchronized void finalizeBatchAndNotifyDeviceOwnerIfNotEmpty() { synchronized void pause() { Log.d(TAG, "Paused network logging"); mPaused = true; } synchronized void resume() { if (!mPaused) { Log.d(TAG, "Attempted to resume network logging, but logging is not paused."); return; } Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentFullBatchToken + ", LastRetrievedBatch=" + mLastRetrievedFullBatchToken); mPaused = false; // If there is a full batch ready that the device owner hasn't been notified about, do it // now. if (mFullBatch != null && mFullBatch.size() > 0 && mLastRetrievedFullBatchToken != mCurrentFullBatchToken) { scheduleBatchFinalization(); notifyDeviceOwnerLocked(); } } synchronized void discardLogs() { mFullBatch = null; mNetworkEvents = new ArrayList<NetworkEvent>(); Log.d(TAG, "Discarded all network logs"); } @GuardedBy("this") private void finalizeBatchAndNotifyDeviceOwnerLocked() { if (mNetworkEvents.size() > 0) { // finalize the batch and start a new one from scratch mFullBatch = mNetworkEvents; mCurrentFullBatchToken++; mNetworkEvents = new ArrayList<NetworkEvent>(); // notify DO that there's a new non-empty batch waiting Bundle extras = new Bundle(); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " + mCurrentFullBatchToken); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); if (!mPaused) { notifyDeviceOwnerLocked(); } } else { // don't notify the DO, since there are no events; DPC can still retrieve // the last full batch // the last full batch if not paused. 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); Loading @@ -115,10 +152,21 @@ final class NetworkLoggingHandler extends Handler { scheduleBatchFinalization(); } @GuardedBy("this") private void notifyDeviceOwnerLocked() { Bundle extras = new Bundle(); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " + mCurrentFullBatchToken); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); } synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) { if (batchToken != mCurrentFullBatchToken) { return null; } mLastRetrievedFullBatchToken = mCurrentFullBatchToken; return mFullBatch; } } Loading Loading
core/java/android/app/admin/DeviceAdminReceiver.java +10 −1 Original line number Diff line number Diff line Loading @@ -768,6 +768,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { /** * Called when a new batch of security logs can be retrieved. * * <p>If a secondary user or profile is created, this callback won't be received until all users * become affiliated again (even if security logging is enabled). * See {@link DevicePolicyManager#setAffiliationIds} * * <p>This callback is only applicable to device owners. * * @param context The running context as per {@link #onReceive}. Loading @@ -782,13 +786,18 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * ever be called when network logging is enabled. The logs can only be retrieved while network * logging is enabled. * * <p>If a secondary user or profile is created, this callback won't be received until all users * become affiliated again (even if network logging is enabled). It will also no longer be * possible to retrieve the network logs batch with the most recent {@code batchToken} provided * by this callback. See {@link DevicePolicyManager#setAffiliationIds}. * * <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) * @see DevicePolicyManager#retrieveNetworkLogs */ public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken, int networkLogsCount) { Loading
core/java/android/app/admin/DevicePolicyManager.java +47 −21 Original line number Diff line number Diff line Loading @@ -3651,15 +3651,16 @@ public class DevicePolicyManager { /** * Called by a device owner to request a bugreport. * <p> * There must be only one user on the device, managed by the device owner. Otherwise a * {@link SecurityException} will be thrown. * If the device contains secondary users or profiles, they must be affiliated with the device * owner user. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds}. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @return {@code true} if the bugreport collection started successfully, or {@code false} if it * wasn't triggered because a previous bugreport operation is still active (either the * bugreport is still running or waiting for the user to share or decline) * @throws SecurityException if {@code admin} is not a device owner, or if there are users other * than the one managed by the device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. */ public boolean requestBugreport(@NonNull ComponentName admin) { throwIfParentInstance("requestBugreport"); Loading Loading @@ -6631,14 +6632,16 @@ public class DevicePolicyManager { } /** * Called by device owner to control the security logging feature. Logging can only be * enabled on single user devices where the sole user is managed by the device owner. * Called by device owner to control the security logging feature. * * <p> Security logs contain various information intended for security auditing purposes. * See {@link SecurityEvent} for details. * * <p>There must be only one user on the device, managed by the device owner. * Otherwise a {@link SecurityException} will be thrown. * <p><strong>Note:</strong> The device owner won't be able to retrieve security logs if there * are unaffiliated secondary users or profiles on the device, regardless of whether the * feature is enabled. Logs will be discarded if the internal buffer fills up while waiting for * all users to become affiliated. Therefore it's recommended that affiliation ids are set for * new users as soon as possible after provisioning via {@link #setAffiliationIds}. * * @param admin Which device owner this request is associated with. * @param enabled whether security logging should be enabled or not. Loading Loading @@ -6680,13 +6683,16 @@ public class DevicePolicyManager { * <p> Access to the logs is rate limited and it will only return new logs after the device * owner has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}. * * <p>There must be only one user on the device, managed by the device owner. * Otherwise a {@link SecurityException} will be thrown. * <p>If there is any other user or profile on the device, it must be affiliated with the * device owner. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds} * * @param admin Which device owner this request is associated with. * @return the new batch of security logs which is a list of {@link SecurityEvent}, * or {@code null} if rate limitation is exceeded or if logging is currently disabled. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see DeviceAdminReceiver#onSecurityLogsAvailable */ public @Nullable List<SecurityEvent> retrieveSecurityLogs(@NonNull ComponentName admin) { throwIfParentInstance("retrieveSecurityLogs"); Loading Loading @@ -6726,14 +6732,17 @@ public class DevicePolicyManager { * will result in {@code null} being returned. The device logs are retrieved from a RAM region * which is not guaranteed to be corruption-free during power cycles, as a result be cautious * about data corruption when parsing. </strong> * <p> * There must be only one user on the device, managed by the device owner. Otherwise a * {@link SecurityException} will be thrown. * * <p>If there is any other user or profile on the device, it must be affiliated with the * device owner. Otherwise a {@link SecurityException} will be thrown. See * {@link #setAffiliationIds} * * @param admin Which device owner this request is associated with. * @return Device logs from before the latest reboot of the system, or {@code null} if this API * is not supported on the device. * @throws SecurityException if {@code admin} is not a device owner. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see #retrieveSecurityLogs */ public @Nullable List<SecurityEvent> retrievePreRebootSecurityLogs( @NonNull ComponentName admin) { Loading Loading @@ -6939,6 +6948,12 @@ public class DevicePolicyManager { * Indicates the entity that controls the device or profile owner. Two users/profiles are * affiliated if the set of ids set by their device or profile owners intersect. * * <p><strong>Note:</strong> Features that depend on user affiliation (such as security logging * or {@link #bindDeviceAdminServiceAsUser}) won't be available when a secondary user or profile * is created, until it becomes affiliated. Therefore it is recommended that the appropriate * affiliation ids are set by its profile owner as soon as possible after the user/profile is * created. * * @param admin Which profile or device owner this request is associated with. * @param ids A list of opaque non-empty affiliation ids. Duplicate elements will be ignored. * Loading Loading @@ -7138,15 +7153,19 @@ public class DevicePolicyManager { } /** * Called by a device owner to control the network logging feature. Logging can only be * enabled on single user devices where the sole user is managed by the device owner. If a new * user is added on the device, logging is disabled. * Called by a device owner to control the network logging feature. * * <p> Network logs contain DNS lookup and connect() library call events. * * <p><strong>Note:</strong> The device owner won't be able to retrieve network logs if there * are unaffiliated secondary users or profiles on the device, regardless of whether the * feature is enabled. Logs will be discarded if the internal buffer fills up while waiting for * all users to become affiliated. Therefore it's recommended that affiliation ids are set for * new users as soon as possible after provisioning via {@link #setAffiliationIds}. * * @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 SecurityException if {@code admin} is not a device owner. * @see #retrieveNetworkLogs */ public void setNetworkLoggingEnabled(@NonNull ComponentName admin, boolean enabled) { Loading @@ -7164,7 +7183,7 @@ public class DevicePolicyManager { * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Can only * be {@code null} if the caller has MANAGE_USERS permission. * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise. * @throws {@link SecurityException} if {@code admin} is not a device owner and caller has * @throws SecurityException if {@code admin} is not a device owner and caller has * no MANAGE_USERS permission */ public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) { Loading @@ -7190,12 +7209,19 @@ public class DevicePolicyManager { * after the device device owner has been notified via * {@link DeviceAdminReceiver#onNetworkLogsAvailable}. * * <p>If a secondary user or profile is created, calling this method will throw a * {@link SecurityException} until all users become affiliated again. It will also no longer be * possible to retrieve the network logs batch with the most recent batchToken provided * by {@link DeviceAdminReceiver#onNetworkLogsAvailable}. See * {@link DevicePolicyManager#setAffiliationIds}. * * @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 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. * @throws SecurityException if {@code admin} is not a device owner, or there is at least one * profile or secondary user that is not affiliated with the device owner user. * @see DeviceAdminReceiver#onNetworkLogsAvailable */ public @Nullable List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin, Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +175 −122 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java +38 −3 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.util.Slog; import com.android.server.ServiceThread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -130,6 +129,8 @@ final class NetworkLogger { Log.d(TAG, "Stopping network logging"); // stop the logging regardless of whether we fail to unregister listener mIsLoggingEnabled.set(false); discardLogs(); try { if (!checkIpConnectivityMetricsService()) { // the IIpConnectivityMetrics service should have been present at this point Loading @@ -140,9 +141,43 @@ final class NetworkLogger { return mIpConnectivityMetrics.unregisterNetdEventCallback(); } catch (RemoteException re) { Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re); return true; } finally { if (mHandlerThread != null) { mHandlerThread.quitSafely(); return true; } } } /** * If logs are being collected, keep collecting them but stop notifying the device owner that * new logs are available (since they cannot be retrieved) */ void pause() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.pause(); } } /** * If logs are being collected, start notifying the device owner when logs are ready to be * collected again (if it was paused). * <p>If logging is enabled and there are logs ready to be retrieved, this method will attempt * to notify the device owner. Therefore calling identity should be cleared before calling it * (in case the method is called from a user other than the DO's user). */ void resume() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.resume(); } } /** * Discard all collected logs. */ void discardLogs() { if (mNetworkLoggingHandler != null) { mNetworkLoggingHandler.discardLogs(); } } Loading
services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java +62 −14 Original line number Diff line number Diff line Loading @@ -55,10 +55,16 @@ final class NetworkLoggingHandler extends Handler { @GuardedBy("this") private ArrayList<NetworkEvent> mFullBatch; // each full batch is represented by its token, which the DPC has to provide back to revieve it @GuardedBy("this") private boolean mPaused = false; // each full batch is represented by its token, which the DPC has to provide back to retrieve it @GuardedBy("this") private long mCurrentFullBatchToken; @GuardedBy("this") private long mLastRetrievedFullBatchToken; NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) { super(looper); mDpm = dpm; Loading @@ -70,15 +76,19 @@ final class NetworkLoggingHandler extends Handler { case LOG_NETWORK_EVENT_MSG: { NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY); if (networkEvent != null) { synchronized (NetworkLoggingHandler.this) { mNetworkEvents.add(networkEvent); if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) { finalizeBatchAndNotifyDeviceOwnerIfNotEmpty(); finalizeBatchAndNotifyDeviceOwnerLocked(); } } } break; } case FINALIZE_BATCH_MSG: { finalizeBatchAndNotifyDeviceOwnerIfNotEmpty(); synchronized (NetworkLoggingHandler.this) { finalizeBatchAndNotifyDeviceOwnerLocked(); } break; } } Loading @@ -91,22 +101,49 @@ final class NetworkLoggingHandler extends Handler { + "ms from now."); } private synchronized void finalizeBatchAndNotifyDeviceOwnerIfNotEmpty() { synchronized void pause() { Log.d(TAG, "Paused network logging"); mPaused = true; } synchronized void resume() { if (!mPaused) { Log.d(TAG, "Attempted to resume network logging, but logging is not paused."); return; } Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentFullBatchToken + ", LastRetrievedBatch=" + mLastRetrievedFullBatchToken); mPaused = false; // If there is a full batch ready that the device owner hasn't been notified about, do it // now. if (mFullBatch != null && mFullBatch.size() > 0 && mLastRetrievedFullBatchToken != mCurrentFullBatchToken) { scheduleBatchFinalization(); notifyDeviceOwnerLocked(); } } synchronized void discardLogs() { mFullBatch = null; mNetworkEvents = new ArrayList<NetworkEvent>(); Log.d(TAG, "Discarded all network logs"); } @GuardedBy("this") private void finalizeBatchAndNotifyDeviceOwnerLocked() { if (mNetworkEvents.size() > 0) { // finalize the batch and start a new one from scratch mFullBatch = mNetworkEvents; mCurrentFullBatchToken++; mNetworkEvents = new ArrayList<NetworkEvent>(); // notify DO that there's a new non-empty batch waiting Bundle extras = new Bundle(); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " + mCurrentFullBatchToken); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); if (!mPaused) { notifyDeviceOwnerLocked(); } } else { // don't notify the DO, since there are no events; DPC can still retrieve // the last full batch // the last full batch if not paused. 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); Loading @@ -115,10 +152,21 @@ final class NetworkLoggingHandler extends Handler { scheduleBatchFinalization(); } @GuardedBy("this") private void notifyDeviceOwnerLocked() { Bundle extras = new Bundle(); extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentFullBatchToken); extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, mFullBatch.size()); Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: " + mCurrentFullBatchToken); mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras); } synchronized List<NetworkEvent> retrieveFullLogBatch(long batchToken) { if (batchToken != mCurrentFullBatchToken) { return null; } mLastRetrievedFullBatchToken = mCurrentFullBatchToken; return mFullBatch; } } Loading