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

Commit e64fa9e7 authored by Alex Johnston's avatar Alex Johnston
Browse files

Allow PO to enable network logging on work profile

Changes
* The profile owner can enable network logging
  on the work profile.
* The network logs only include work profile
  network activity (not personal profile activity).

Bug: 170460270
Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest
      atest com.android.server.devicepolicy.NetworkEventTest
      atest com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testNetworkLogging
      atest com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testNetworkLogging
      atest com.android.cts.devicepolicy.DeviceOwnerTest#testNetworkLoggingWithTwoUsers
      atest com.android.cts.devicepolicy.DeviceOwnerTest#testNetworkLoggingWithSingleUser
      atest com.android.cts.devicepolicy.DeviceOwnerTest#testNetworkLogging_multipleBatches
Change-Id: I4727ba7cbc62f9cd187f82a9527f0475345fd555
parent ea106b87
Loading
Loading
Loading
Loading
+33 −21
Original line number Diff line number Diff line
@@ -11795,8 +11795,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:
@@ -11836,7 +11839,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
     */
@@ -11850,14 +11853,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");
@@ -11869,9 +11874,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.
     *
@@ -11883,11 +11893,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.
@@ -11895,8 +11905,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
     */
@@ -12015,11 +12026,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
@@ -781,8 +781,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);
@@ -7527,6 +7526,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));
@@ -8351,6 +8364,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        deleteTransferOwnershipBundleLocked(userId);
        toggleBackupServiceActive(userId, true);
        applyManagedProfileRestrictionIfDeviceOwnerLocked();
        setNetworkLoggingActiveInternal(false);
    }
    @Override
@@ -14178,7 +14192,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()) {
@@ -14186,11 +14202,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);
@@ -14208,7 +14224,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"
@@ -14228,6 +14250,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()),
@@ -14248,11 +14289,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.");
@@ -14270,7 +14313,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();
                }
@@ -14297,7 +14342,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));
@@ -14307,8 +14354,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;
    }
    /*
@@ -14325,9 +14372,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()) {
@@ -14340,34 +14391,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);
@@ -14387,7 +14439,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());
    }
    /**
@@ -14451,8 +14503,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
@@ -4352,6 +4352,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