androiddevice-admin

Android DeviceAdminReceiver: onNetworkLogsAvailable intent never received


UPDATE

I'm noticing that I actually am receiving the NETWORK_LOGS_AVAILABLE intent! The problem is, it's taking a very long time (over an hour?) to receive it.

Is there any known way to increase the frequency of receiving these events?

Original Question

I am trying to process DNS events that can now be read after receiving the onNetworkLogsAvailable intent in a DeviceAdminReceiver application. This functionality was made available as of Android 8.0.

For some reason, I am never receiving this intent, even though I am successfully calling the setNetworkLoggingEnabled method. Upon admin being enabled, I am receiving the ACTION_DEVICE_ADMIN_ENABLED event, but nothing else after that.

Here's where I enable network logging:

public class NetworkAdminReceiver extends DeviceAdminReceiver {
    @Override
    public void onEnabled(Context context, Intent intent) {
        DevicePolicyManager manager =
            (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        if ( manager == null )
        {
            throw new IllegalStateException("Unable to get DevicePolicyManager");
        }
        if (manager.isDeviceOwnerApp(context.getPackageName())) {
            manager.setNetworkLoggingEnabled(getWho(context), true);
        }
        else
        {
            Toast.makeText(context, "This application is not device owner. DNS logging only works" +
                " when this application is setup as the Device Owner", Toast.LENGTH_LONG).show();
        }
    }
    // *snip* rest of class
}

Although I am not sure whether it's required (cannot find in documentation), I've also added the NETWORK_LOGS_AVAILABLE intent action to the receiver's filter:

<receiver android:name=".admin.NetworkAdminReceiver"
        android:label="@string/device_admin"
        android:description="@string/device_admin_description"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
            android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
        <action android:name="android.app.action.NETWORK_LOGS_AVAILABLE"/>
    </intent-filter>
</receiver>

The application is marked as the device owner, network logging is enabled, and yet I never receive the intent. The only explanation I could think of is that network logs do not become available very frequently, but I could find no documentation supporting this theory.

I am also currently only testing this in the emulator. I am unsure if that would have an effect on this, though I cannot see how it would.

Is there anything that I am missing in order to properly receive the network logs via the DeviceAdminReceiver?


Solution

  • I'm afraid there's no elegant solution.

    This limitation looks like it was made intentionally. As you can see in the sources, the event is triggered when hard-coded thresholds are reached. It's either 1200 events or 1.5H timeout, whichever comes first. I did not manage to find any usable hooks in the NetworkLogger. They definitely did not want users to meddle with it.

    The only option I see is to use reflection to get access to the hidden API. The most straightforward, IMHO, is to get a handle to the IIpConnectivityMetrics service and use it to subscribe to the network events. I did not test this solution myself, though.