Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3873b62 authored by Alex Johnston's avatar Alex Johnston Committed by Android (Google) Code Review
Browse files

Merge "Allow PO to enable network logging on work profile"

parents dbaf2f85 e64fa9e7
Loading
Loading
Loading
Loading
+33 −21
Original line number Diff line number Diff line
@@ -11796,8 +11796,11 @@ public class DevicePolicyManager {
    }
    /**
     * Called by a device owner or delegated app with {@link #DELEGATION_NETWORK_LOGGING} to
     * control the network logging feature.
     * Called by a device owner, profile owner of a managed profile or delegated app with
     * {@link #DELEGATION_NETWORK_LOGGING} to control the network logging feature.
     *
     * <p> When network logging is enabled by a profile owner, the network logs will only include
     * work profile network activity, not activity on the personal profile.
     *
     * <p> Network logs contain DNS lookup and connect() library call events. The following library
     *     functions are recorded while network logging is active:
@@ -11837,7 +11840,7 @@ public class DevicePolicyManager {
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
     *        {@code null} if called by a delegated app.
     * @param enabled whether network logging should be enabled or not.
     * @throws SecurityException if {@code admin} is not a device owner.
     * @throws SecurityException if {@code admin} is not a device owner or profile owner.
     * @see #setAffiliationIds
     * @see #retrieveNetworkLogs
     */
@@ -11851,14 +11854,16 @@ public class DevicePolicyManager {
    }
    /**
     * Return whether network logging is enabled by a device owner.
     * Return whether network logging is enabled by a device owner or profile owner of
     * a managed profile.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Can only
     * be {@code null} if the caller is a delegated app with {@link #DELEGATION_NETWORK_LOGGING}
     * or has MANAGE_USERS permission.
     * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a device owner and caller has
     * no MANAGE_USERS permission
     * @return {@code true} if network logging is enabled by device owner or profile owner,
     * {@code false} otherwise.
     * @throws SecurityException if {@code admin} is not a device owner or profile owner and
     * caller has no MANAGE_USERS permission
     */
    public boolean isNetworkLoggingEnabled(@Nullable ComponentName admin) {
        throwIfParentInstance("isNetworkLoggingEnabled");
@@ -11870,9 +11875,14 @@ public class DevicePolicyManager {
    }
    /**
     * Called by device owner or delegated app with {@link #DELEGATION_NETWORK_LOGGING} to retrieve
     * the most recent batch of network logging events.
     * A device owner has to provide a batchToken provided as part of
     * Called by device owner, profile owner of a managed profile or delegated app with
     * {@link #DELEGATION_NETWORK_LOGGING} to retrieve the most recent batch of
     * network logging events.
     *
     * <p> When network logging is enabled by a profile owner, the network logs will only include
     * work profile network activity, not activity on the personal profile.
     *
     * A device owner or profile 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.
     *
@@ -11884,11 +11894,11 @@ 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}.
     * <p>If the caller is not a profile owner and 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, or
     *        {@code null} if called by a delegated app.
@@ -11896,8 +11906,9 @@ public class DevicePolicyManager {
     * @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 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.
     * @throws SecurityException if {@code admin} is not a device owner, profile owner or if the
     * {@code admin} is not a profile owner and there is at least one profile or secondary user
     * that is not affiliated with the device.
     * @see #setAffiliationIds
     * @see DeviceAdminReceiver#onNetworkLogsAvailable
     */
@@ -12016,11 +12027,12 @@ public class DevicePolicyManager {
    }
    /**
     * Called by the system to get the time at which the device owner last retrieved network logging
     * events.
     * Called by the system to get the time at which the device owner or profile owner of a
     * managed profile last retrieved network logging events.
     *
     * @return the time at which the device owner most recently retrieved network logging events, in
     *         milliseconds since epoch; -1 if network logging events were never retrieved.
     * @return the time at which the device owner or profile owner most recently retrieved network
     *         logging events, in milliseconds since epoch; -1 if network logging events were
     *         never retrieved.
     * @throws SecurityException if the caller is not the device owner, does not hold the
     *         MANAGE_USERS permission and is not the system.
     *
+88 −32
Original line number Diff line number Diff line
@@ -782,8 +782,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
             * however it's too early in the boot process to register with IIpConnectivityMetrics
             * to listen for events.
             */
            if (Intent.ACTION_USER_STARTED.equals(action)
                    && userHandle == mOwners.getDeviceOwnerUserId()) {
            if (Intent.ACTION_USER_STARTED.equals(action) && userHandle == UserHandle.USER_SYSTEM) {
                synchronized (getLockObject()) {
                    if (isNetworkLoggingEnabledInternalLocked()) {
                        setNetworkLoggingActiveInternal(true);
@@ -7533,6 +7532,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        sendActiveAdminCommand(action, extras, deviceOwnerUserId, receiverComponent);
    }
    void sendDeviceOwnerOrProfileOwnerCommand(String action, Bundle extras, int userId) {
        if (userId == UserHandle.USER_ALL) {
            userId = UserHandle.USER_SYSTEM;
        }
        ComponentName receiverComponent = null;
        if (action.equals(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE)) {
            receiverComponent = resolveDelegateReceiver(DELEGATION_NETWORK_LOGGING, action, userId);
        }
        if (receiverComponent == null) {
            receiverComponent = getOwnerComponent(userId);
        }
        sendActiveAdminCommand(action, extras, userId, receiverComponent);
    }
    private void sendProfileOwnerCommand(String action, Bundle extras, @UserIdInt int userId) {
        sendActiveAdminCommand(action, extras, userId,
                mOwners.getProfileOwnerComponent(userId));
@@ -8357,6 +8370,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        deleteTransferOwnershipBundleLocked(userId);
        toggleBackupServiceActive(userId, true);
        applyManagedProfileRestrictionIfDeviceOwnerLocked();
        setNetworkLoggingActiveInternal(false);
    }
    @Override
@@ -14184,7 +14198,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return;
        }
        final CallerIdentity caller = getCallerIdentity(admin, packageName);
        Preconditions.checkCallAuthorization((caller.hasAdminComponent() && isDeviceOwner(caller))
        Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                && (isDeviceOwner(caller)
                || (isProfileOwner(caller) && isManagedProfile(caller.getUserId()))))
                || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING)));
        synchronized (getLockObject()) {
@@ -14192,11 +14208,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                // already in the requested state
                return;
            }
            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
            deviceOwner.isNetworkLoggingEnabled = enabled;
            final ActiveAdmin activeAdmin = getDeviceOrProfileOwnerAdminLocked(caller.getUserId());
            activeAdmin.isNetworkLoggingEnabled = enabled;
            if (!enabled) {
                deviceOwner.numNetworkLoggingNotifications = 0;
                deviceOwner.lastNetworkLoggingNotificationTimeMs = 0;
                activeAdmin.numNetworkLoggingNotifications = 0;
                activeAdmin.lastNetworkLoggingNotificationTimeMs = 0;
            }
            saveSettingsLocked(caller.getUserId());
            setNetworkLoggingActiveInternal(enabled);
@@ -14214,7 +14230,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        synchronized (getLockObject()) {
            mInjector.binderWithCleanCallingIdentity(() -> {
                if (active) {
                    mNetworkLogger = new NetworkLogger(this, mInjector.getPackageManagerInternal());
                    if (mNetworkLogger == null) {
                        final int affectedUserId = getNetworkLoggingAffectedUser();
                        mNetworkLogger = new NetworkLogger(this,
                                mInjector.getPackageManagerInternal(),
                                affectedUserId == UserHandle.USER_SYSTEM
                                        ? UserHandle.USER_ALL : affectedUserId);
                    }
                    if (!mNetworkLogger.startNetworkLogging()) {
                        mNetworkLogger = null;
                        Slog.wtf(LOG_TAG, "Network logging could not be started due to the logging"
@@ -14234,6 +14256,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }
    private @UserIdInt int getNetworkLoggingAffectedUser() {
        synchronized (getLockObject()) {
            if (mOwners.hasDeviceOwner()) {
                return mOwners.getDeviceOwnerUserId();
            } else {
                return mInjector.binderWithCleanCallingIdentity(
                        () -> getManagedUserId(UserHandle.USER_SYSTEM));
            }
        }
    }
    private ActiveAdmin getNetworkLoggingControllingAdminLocked() {
        int affectedUserId = getNetworkLoggingAffectedUser();
        if (affectedUserId < 0) {
            return null;
        }
        return getDeviceOrProfileOwnerAdminLocked(affectedUserId);
    }
    @Override
    public long forceNetworkLogs() {
        Preconditions.checkCallAuthorization(isAdb(getCallerIdentity()),
@@ -14254,11 +14295,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    @GuardedBy("getLockObject()")
    private void maybePauseDeviceWideLoggingLocked() {
        if (!areAllUsersAffiliatedWithDeviceLocked()) {
            if (mOwners.hasDeviceOwner()) {
                Slog.i(LOG_TAG, "There are unaffiliated users, network logging will be "
                        + "paused if enabled.");
                if (mNetworkLogger != null) {
                    mNetworkLogger.pause();
                }
            }
            if (!isOrganizationOwnedDeviceWithManagedProfile()) {
                Slog.i(LOG_TAG, "Not org-owned managed profile device, security logging will be "
                        + "paused if enabled.");
@@ -14276,7 +14319,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            if (allUsersAffiliated || orgOwnedProfileDevice) {
                mSecurityLogMonitor.resume();
            }
            if (allUsersAffiliated) {
            // If there is no device owner, then per-user network logging may be enabled for the
            // managed profile. In which case, all users do not need to be affiliated.
            if (allUsersAffiliated || !mOwners.hasDeviceOwner()) {
                if (mNetworkLogger != null) {
                    mNetworkLogger.resume();
                }
@@ -14303,7 +14348,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return false;
        }
        final CallerIdentity caller = getCallerIdentity(admin, packageName);
        Preconditions.checkCallAuthorization((caller.hasAdminComponent() &&  isDeviceOwner(caller))
        Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                &&  (isDeviceOwner(caller)
                || (isProfileOwner(caller) && isManagedProfile(caller.getUserId()))))
                || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING))
                || hasCallingOrSelfPermission(permission.MANAGE_USERS));
@@ -14313,8 +14360,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    }
    private boolean isNetworkLoggingEnabledInternalLocked() {
        ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
        return (deviceOwner != null) && deviceOwner.isNetworkLoggingEnabled;
        ActiveAdmin activeAdmin = getNetworkLoggingControllingAdminLocked();
        return (activeAdmin != null) && activeAdmin.isNetworkLoggingEnabled;
    }
    /*
@@ -14331,9 +14378,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            return null;
        }
        final CallerIdentity caller = getCallerIdentity(admin, packageName);
        Preconditions.checkCallAuthorization((caller.hasAdminComponent() &&  isDeviceOwner(caller))
        Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                &&  (isDeviceOwner(caller)
                || (isProfileOwner(caller) && isManagedProfile(caller.getUserId()))))
                || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_NETWORK_LOGGING)));
        if (mOwners.hasDeviceOwner()) {
            checkAllUsersAreAffiliatedWithDevice();
        }
        synchronized (getLockObject()) {
            if (mNetworkLogger == null || !isNetworkLoggingEnabledInternalLocked()) {
@@ -14346,34 +14397,35 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    .write();
            final long currentTime = System.currentTimeMillis();
            DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM);
            DevicePolicyData policyData = getUserData(caller.getUserId());
            if (currentTime > policyData.mLastNetworkLogsRetrievalTime) {
                policyData.mLastNetworkLogsRetrievalTime = currentTime;
                saveSettingsLocked(UserHandle.USER_SYSTEM);
                saveSettingsLocked(caller.getUserId());
            }
            return mNetworkLogger.retrieveLogs(batchToken);
        }
    }
    private void sendNetworkLoggingNotificationLocked() {
        final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
        if (deviceOwner == null || !deviceOwner.isNetworkLoggingEnabled) {
        ensureLocked();
        final ActiveAdmin activeAdmin = getNetworkLoggingControllingAdminLocked();
        if (activeAdmin == null || !activeAdmin.isNetworkLoggingEnabled) {
            return;
        }
        if (deviceOwner.numNetworkLoggingNotifications >=
                ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) {
        if (activeAdmin.numNetworkLoggingNotifications
                >= ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) {
            return;
        }
        final long now = System.currentTimeMillis();
        if (now - deviceOwner.lastNetworkLoggingNotificationTimeMs < MS_PER_DAY) {
        if (now - activeAdmin.lastNetworkLoggingNotificationTimeMs < MS_PER_DAY) {
            return;
        }
        deviceOwner.numNetworkLoggingNotifications++;
        if (deviceOwner.numNetworkLoggingNotifications
        activeAdmin.numNetworkLoggingNotifications++;
        if (activeAdmin.numNetworkLoggingNotifications
                >= ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) {
            deviceOwner.lastNetworkLoggingNotificationTimeMs = 0;
            activeAdmin.lastNetworkLoggingNotificationTimeMs = 0;
        } else {
            deviceOwner.lastNetworkLoggingNotificationTimeMs = now;
            activeAdmin.lastNetworkLoggingNotificationTimeMs = now;
        }
        final PackageManagerInternal pm = mInjector.getPackageManagerInternal();
        final Intent intent = new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
@@ -14393,7 +14445,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                        .bigText(mContext.getString(R.string.network_logging_notification_text)))
                .build();
        mInjector.getNotificationManager().notify(SystemMessage.NOTE_NETWORK_LOGGING, notification);
        saveSettingsLocked(mOwners.getDeviceOwnerUserId());
        saveSettingsLocked(activeAdmin.getUserHandle().getIdentifier());
    }
    /**
@@ -14457,8 +14509,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    @Override
    public long getLastNetworkLogRetrievalTime() {
        final CallerIdentity caller = getCallerIdentity();
        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
        return getUserData(UserHandle.USER_SYSTEM).mLastNetworkLogsRetrievalTime;
        Preconditions.checkCallAuthorization(isDeviceOwner(caller)
                || (isProfileOwner(caller) && isManagedProfile(caller.getUserId()))
                || canManageUsers(caller));
        final int affectedUserId = getNetworkLoggingAffectedUser();
        return affectedUserId >= 0 ? getUserData(affectedUserId).mLastNetworkLogsRetrievalTime : -1;
    }
    @Override
+27 −6
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Bundle;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;

@@ -47,6 +48,10 @@ final class NetworkLogger {
    private final PackageManagerInternal mPm;
    private final AtomicBoolean mIsLoggingEnabled = new AtomicBoolean(false);

    // The target userId to collect network events on. The target userId will be
    // {@link android.os.UserHandle#USER_ALL} if network events should be collected for all users.
    private final int mTargetUserId;

    private IIpConnectivityMetrics mIpConnectivityMetrics;
    private ServiceThread mHandlerThread;
    private NetworkLoggingHandler mNetworkLoggingHandler;
@@ -58,6 +63,11 @@ final class NetworkLogger {
            if (!mIsLoggingEnabled.get()) {
                return;
            }
            // If the network logging was enabled by the profile owner, then do not
            // include events in the personal profile.
            if (!shouldLogNetworkEvent(uid)) {
                return;
            }
            DnsEvent dnsEvent = new DnsEvent(hostname, ipAddresses, ipAddressesCount,
                    mPm.getNameForUid(uid), timestamp);
            sendNetworkEvent(dnsEvent);
@@ -68,6 +78,11 @@ final class NetworkLogger {
            if (!mIsLoggingEnabled.get()) {
                return;
            }
            // If the network logging was enabled by the profile owner, then do not
            // include events in the personal profile.
            if (!shouldLogNetworkEvent(uid)) {
                return;
            }
            ConnectEvent connectEvent = new ConnectEvent(ipAddr, port, mPm.getNameForUid(uid),
                    timestamp);
            sendNetworkEvent(connectEvent);
@@ -81,11 +96,17 @@ final class NetworkLogger {
            msg.setData(bundle);
            mNetworkLoggingHandler.sendMessage(msg);
        }

        private boolean shouldLogNetworkEvent(int uid) {
            return mTargetUserId == UserHandle.USER_ALL
                    || mTargetUserId == UserHandle.getUserId(uid);
        }
    };

    NetworkLogger(DevicePolicyManagerService dpm, PackageManagerInternal pm) {
    NetworkLogger(DevicePolicyManagerService dpm, PackageManagerInternal pm, int targetUserId) {
        mDpm = dpm;
        mPm = pm;
        mTargetUserId = targetUserId;
    }

    private boolean checkIpConnectivityMetricsService() {
@@ -114,7 +135,7 @@ final class NetworkLogger {
                        /* allowIo */ false);
                mHandlerThread.start();
                mNetworkLoggingHandler = new NetworkLoggingHandler(mHandlerThread.getLooper(),
                        mDpm);
                        mDpm, mTargetUserId);
                mNetworkLoggingHandler.scheduleBatchFinalization();
                mIsLoggingEnabled.set(true);
                return true;
@@ -153,7 +174,7 @@ final class NetworkLogger {
    }

    /**
     * If logs are being collected, keep collecting them but stop notifying the device owner that
     * If logs are being collected, keep collecting them but stop notifying the admin that
     * new logs are available (since they cannot be retrieved)
     */
    void pause() {
@@ -163,11 +184,11 @@ final class NetworkLogger {
    }

    /**
     * If logs are being collected, start notifying the device owner when logs are ready to be
     * If logs are being collected, start notifying the admin 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).
     * to notify the admin. Therefore calling identity should be cleared before calling it
     * (in case the method is called from a user other than the admin's user).
     */
    void resume() {
        if (mNetworkLoggingHandler != null) {
+33 −27

File changed.

Preview size limit exceeded, changes collapsed.

+62 −0
Original line number Diff line number Diff line
@@ -4353,6 +4353,68 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);
    }

    @Test
    public void testSetNetworkLoggingEnabled_asPo() throws Exception {
        final int managedProfileUserId = CALLER_USER_HANDLE;
        final int managedProfileAdminUid =
                UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID);
        mContext.binder.callingUid = managedProfileAdminUid;
        mContext.applicationInfo = new ApplicationInfo();
        mContext.packageName = admin1.getPackageName();
        addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.S);
        when(getServices().iipConnectivityMetrics
                .addNetdEventCallback(anyInt(), anyObject())).thenReturn(true);

        // Check no logs have been retrieved so far.
        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);

        // Enable network logging
        dpm.setNetworkLoggingEnabled(admin1, true);
        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);

        // Retrieve the network logs and verify timestamp has been updated.
        final long beforeRetrieval = System.currentTimeMillis();

        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);

        final long networkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
        final long afterRetrieval = System.currentTimeMillis();
        assertThat(networkLogRetrievalTime >= beforeRetrieval).isTrue();
        assertThat(networkLogRetrievalTime <= afterRetrieval).isTrue();
    }

    @Test
    public void testSetNetworkLoggingEnabled_asPoOfOrgOwnedDevice() throws Exception {
        // Setup profile owner on organization-owned device
        final int MANAGED_PROFILE_ADMIN_UID =
                UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
        configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);

        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
        mContext.packageName = admin1.getPackageName();
        mContext.applicationInfo = new ApplicationInfo();
        when(getServices().iipConnectivityMetrics
                .addNetdEventCallback(anyInt(), anyObject())).thenReturn(true);

        // Check no logs have been retrieved so far.
        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);

        // Enable network logging
        dpm.setNetworkLoggingEnabled(admin1, true);
        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);

        // Retrieve the network logs and verify timestamp has been updated.
        final long beforeRetrieval = System.currentTimeMillis();

        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);

        final long networkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
        final long afterRetrieval = System.currentTimeMillis();
        assertThat(networkLogRetrievalTime >= beforeRetrieval).isTrue();
        assertThat(networkLogRetrievalTime <= afterRetrieval).isTrue();
    }

    @Test
    public void testGetBindDeviceAdminTargetUsers() throws Exception {
        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS);
Loading