DO NOT MERGE [DPM] DO can start network logging and listen for events
This CL adds: 1) Setter and getter in DPM to manipulate logging switch (retrieval method to come in a subsequent CL(s)). 2) A way for DPM to register to listen for events. 3) Skeleton of NetworkLogger class (more to come in subsequent CL(s)). Bug: 29748723 Change-Id: I5c04662ccc6febd2ba294b0eaca1ed1da9c16e47
This commit is contained in:
@@ -202,6 +202,7 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/net/IIpConnectivityMetrics.aidl \
|
||||
core/java/android/net/IEthernetManager.aidl \
|
||||
core/java/android/net/IEthernetServiceListener.aidl \
|
||||
core/java/android/net/INetdEventCallback.aidl \
|
||||
core/java/android/net/INetworkManagementEventObserver.aidl \
|
||||
core/java/android/net/INetworkPolicyListener.aidl \
|
||||
core/java/android/net/INetworkPolicyManager.aidl \
|
||||
|
||||
@@ -6609,4 +6609,46 @@ public class DevicePolicyManager {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <p> Network logs contain DNS lookup and connect() library call events.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setNetworkLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
|
||||
throwIfParentInstance("setNetworkLoggingEnabled");
|
||||
try {
|
||||
mService.setNetworkLoggingEnabled(admin, enabled);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether network logging is enabled by a device owner.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
|
||||
* @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.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isNetworkLoggingEnabled(@NonNull ComponentName admin) {
|
||||
throwIfParentInstance("isNetworkLoggingEnabled");
|
||||
try {
|
||||
return mService.isNetworkLoggingEnabled(admin);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,4 +311,7 @@ interface IDevicePolicyManager {
|
||||
|
||||
void setBackupServiceEnabled(in ComponentName admin, boolean enabled);
|
||||
boolean isBackupServiceEnabled(in ComponentName admin);
|
||||
|
||||
void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled);
|
||||
boolean isNetworkLoggingEnabled(in ComponentName admin);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.net;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
import android.net.INetdEventCallback;
|
||||
|
||||
/** {@hide} */
|
||||
interface IIpConnectivityMetrics {
|
||||
@@ -27,4 +28,13 @@ interface IIpConnectivityMetrics {
|
||||
* or -1 if the event was dropped due to rate limiting.
|
||||
*/
|
||||
int logEvent(in ConnectivityMetricsEvent event);
|
||||
|
||||
/**
|
||||
* At most one callback can be registered (by DevicePolicyManager).
|
||||
* @return status {@code true} if registering/unregistering of the callback was successful,
|
||||
* {@code false} otherwise (might happen if IIpConnectivityMetrics is not available,
|
||||
* if it happens make sure you call it when the service is up in the caller)
|
||||
*/
|
||||
boolean registerNetdEventCallback(in INetdEventCallback callback);
|
||||
boolean unregisterNetdEventCallback();
|
||||
}
|
||||
|
||||
47
core/java/android/net/INetdEventCallback.aidl
Normal file
47
core/java/android/net/INetdEventCallback.aidl
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
/** {@hide} */
|
||||
oneway interface INetdEventCallback {
|
||||
|
||||
/**
|
||||
* Reports a single DNS lookup function call.
|
||||
* This method must not block or perform long-running operations.
|
||||
*
|
||||
* @param hostname the name that was looked up.
|
||||
* @param ipAddresses (possibly a subset of) the IP addresses returned.
|
||||
* At most {@link #DNS_REPORTED_IP_ADDRESSES_LIMIT} addresses are logged.
|
||||
* @param ipAddressesCount the number of IP addresses returned. May be different from the length
|
||||
* of ipAddresses if there were too many addresses to log.
|
||||
* @param timestamp the timestamp at which the query was reported by netd.
|
||||
* @param uid the UID of the application that performed the query.
|
||||
*/
|
||||
void onDnsEvent(String hostname, in String[] ipAddresses, int ipAddressesCount, long timestamp,
|
||||
int uid);
|
||||
|
||||
/**
|
||||
* Reports a single connect library call.
|
||||
* This method must not block or perform long-running operations.
|
||||
*
|
||||
* @param ipAddr destination IP address.
|
||||
* @param port destination port number.
|
||||
* @param timestamp the timestamp at which the call was reported by netd.
|
||||
* @param uid the UID of the application that performed the connection.
|
||||
*/
|
||||
void onConnectEvent(String ipAddr, int port, long timestamp, int uid);
|
||||
}
|
||||
@@ -19,10 +19,13 @@ package com.android.server.connectivity;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
import android.net.IIpConnectivityMetrics;
|
||||
import android.net.INetdEventCallback;
|
||||
import android.net.metrics.ApfProgramEvent;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Process;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
@@ -260,6 +263,33 @@ final public class IpConnectivityMetrics extends SystemService {
|
||||
private void enforcePermission(String what) {
|
||||
getContext().enforceCallingOrSelfPermission(what, "IpConnectivityMetrics");
|
||||
}
|
||||
|
||||
private void enforceNetdEventListeningPermission() {
|
||||
final int uid = Binder.getCallingUid();
|
||||
if (uid != Process.SYSTEM_UID) {
|
||||
throw new SecurityException(String.format("Uid %d has no permission to listen for"
|
||||
+ " netd events.", uid));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerNetdEventCallback(INetdEventCallback callback) {
|
||||
enforceNetdEventListeningPermission();
|
||||
if (mNetdListener == null) {
|
||||
return false;
|
||||
}
|
||||
return mNetdListener.registerNetdEventCallback(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unregisterNetdEventCallback() {
|
||||
enforceNetdEventListeningPermission();
|
||||
if (mNetdListener == null) {
|
||||
// if the service is null, we aren't registered anyway
|
||||
return true;
|
||||
}
|
||||
return mNetdListener.unregisterNetdEventCallback();
|
||||
}
|
||||
};
|
||||
|
||||
private static final ToIntFunction<Context> READ_BUFFER_SIZE = (ctx) -> {
|
||||
|
||||
@@ -20,10 +20,12 @@ import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.ConnectivityManager.NetworkCallback;
|
||||
import android.net.Network;
|
||||
import android.net.INetdEventCallback;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.metrics.DnsEvent;
|
||||
import android.net.metrics.INetdEventListener;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -119,6 +121,21 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
}
|
||||
};
|
||||
|
||||
// Callback should only be registered/unregistered when logging is being enabled/disabled in DPM
|
||||
// by the device owner. It's DevicePolicyManager's responsibility to ensure that.
|
||||
@GuardedBy("this")
|
||||
private INetdEventCallback mNetdEventCallback;
|
||||
|
||||
public synchronized boolean registerNetdEventCallback(INetdEventCallback callback) {
|
||||
mNetdEventCallback = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean unregisterNetdEventCallback() {
|
||||
mNetdEventCallback = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public NetdEventListenerService(Context context) {
|
||||
this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
|
||||
}
|
||||
@@ -136,7 +153,8 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
// Called concurrently by multiple binder threads.
|
||||
// This method must not block or perform long-running operations.
|
||||
public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
|
||||
String hostname, String[] ipAddresses, int ipAddressesCount, int uid) {
|
||||
String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
|
||||
throws RemoteException {
|
||||
maybeVerboseLog(String.format("onDnsEvent(%d, %d, %d, %d)",
|
||||
netId, eventType, returnCode, latencyMs));
|
||||
|
||||
@@ -146,14 +164,23 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
||||
mEventBatches.put(netId, batch);
|
||||
}
|
||||
batch.addResult((byte) eventType, (byte) returnCode, latencyMs);
|
||||
|
||||
if (mNetdEventCallback != null) {
|
||||
mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount,
|
||||
System.currentTimeMillis(), uid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// Called concurrently by multiple binder threads.
|
||||
// This method must not block or perform long-running operations.
|
||||
public synchronized void onConnectEvent(int netId, int latencyMs, String ipAddr, int port,
|
||||
int uid) {
|
||||
int uid) throws RemoteException {
|
||||
maybeVerboseLog(String.format("onConnectEvent(%d, %d)", netId, latencyMs));
|
||||
|
||||
if (mNetdEventCallback != null) {
|
||||
mNetdEventCallback.onConnectEvent(ipAddr, port, System.currentTimeMillis(), uid);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void dump(PrintWriter writer) {
|
||||
|
||||
@@ -77,8 +77,10 @@ import android.graphics.Color;
|
||||
import android.media.AudioManager;
|
||||
import android.media.IAudioService;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IIpConnectivityMetrics;
|
||||
import android.net.ProxyInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.AsyncTask;
|
||||
@@ -352,6 +354,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
boolean mIsWatch;
|
||||
|
||||
private final SecurityLogMonitor mSecurityLogMonitor;
|
||||
private NetworkLogger mNetworkLogger;
|
||||
|
||||
private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean();
|
||||
private final AtomicBoolean mRemoteBugreportSharingAccepted = new AtomicBoolean();
|
||||
@@ -478,6 +481,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
|
||||
getSendingUserId());
|
||||
|
||||
/*
|
||||
* Network logging would ideally be started in setDeviceOwnerSystemPropertyLocked(),
|
||||
* 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()
|
||||
&& isNetworkLoggingEnabledInternal()) {
|
||||
setNetworkLoggingActiveInternal(true);
|
||||
}
|
||||
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|
||||
&& userHandle == mOwners.getDeviceOwnerUserId()
|
||||
&& getDeviceOwnerRemoteBugreportUri() != null) {
|
||||
@@ -549,6 +562,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
|
||||
private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
|
||||
private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
|
||||
private static final String TAG_IS_NETWORK_LOGGING_ENABLED = "is_network_logging_enabled";
|
||||
private static final String TAG_ACCOUNT_TYPE = "account-type";
|
||||
private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
|
||||
= "permitted-accessiblity-services";
|
||||
@@ -643,6 +657,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
|
||||
boolean requireAutoTime = false; // Can only be set by a device owner.
|
||||
boolean forceEphemeralUsers = false; // Can only be set by a device owner.
|
||||
boolean isNetworkLoggingEnabled = false; // Can only be set by a device owner.
|
||||
|
||||
ActiveAdmin parentAdmin;
|
||||
final boolean isParent;
|
||||
@@ -851,6 +866,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
|
||||
out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
|
||||
}
|
||||
if (isNetworkLoggingEnabled) {
|
||||
out.startTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
|
||||
out.attribute(null, ATTR_VALUE, Boolean.toString(isNetworkLoggingEnabled));
|
||||
out.endTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
|
||||
}
|
||||
if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
|
||||
out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
|
||||
out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
|
||||
@@ -1037,6 +1057,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
} else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
|
||||
forceEphemeralUsers = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
} else if (TAG_IS_NETWORK_LOGGING_ENABLED.equals(tag)) {
|
||||
isNetworkLoggingEnabled = Boolean.parseBoolean(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
} else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
|
||||
disabledKeyguardFeatures = Integer.parseInt(
|
||||
parser.getAttributeValue(null, ATTR_VALUE));
|
||||
@@ -1277,6 +1300,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
pw.println(requireAutoTime);
|
||||
pw.print(prefix); pw.print("forceEphemeralUsers=");
|
||||
pw.println(forceEphemeralUsers);
|
||||
pw.print(prefix); pw.print("isNetworkLoggingEnabled=");
|
||||
pw.println(isNetworkLoggingEnabled);
|
||||
pw.print(prefix); pw.print("disabledKeyguardFeatures=");
|
||||
pw.println(disabledKeyguardFeatures);
|
||||
pw.print(prefix); pw.print("crossProfileWidgetProviders=");
|
||||
@@ -1403,6 +1428,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
return mContext.getSystemService(NotificationManager.class);
|
||||
}
|
||||
|
||||
IIpConnectivityMetrics getIIpConnectivityMetrics() {
|
||||
return (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface(
|
||||
ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
|
||||
}
|
||||
|
||||
PowerManagerInternal getPowerManagerInternal() {
|
||||
return LocalServices.getService(PowerManagerInternal.class);
|
||||
}
|
||||
@@ -9040,6 +9070,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
if (!isDeviceOwnerManagedSingleUserDevice()) {
|
||||
mInjector.securityLogSetLoggingEnabledProperty(false);
|
||||
Slog.w(LOG_TAG, "Security logging turned off as it's no longer a single user device.");
|
||||
|
||||
getDeviceOwnerAdminLocked().isNetworkLoggingEnabled = false;
|
||||
saveSettingsLocked(mInjector.userHandleGetCallingUserId());
|
||||
setNetworkLoggingActiveInternal(false);
|
||||
Slog.w(LOG_TAG, "Network logging turned off as it's no longer a single user"
|
||||
+ " device.");
|
||||
|
||||
if (mOwners.hasDeviceOwner()) {
|
||||
setBackupServiceEnabledInternal(false);
|
||||
Slog.w(LOG_TAG, "Backup is off as it's a managed device that has more that one user.");
|
||||
@@ -9386,4 +9423,62 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setNetworkLoggingEnabled(ComponentName admin, boolean enabled) {
|
||||
if (!mHasFeature) {
|
||||
return;
|
||||
}
|
||||
Preconditions.checkNotNull(admin);
|
||||
ensureDeviceOwnerManagingSingleUser(admin);
|
||||
|
||||
if (enabled == isNetworkLoggingEnabledInternal()) {
|
||||
// already in the requested state
|
||||
return;
|
||||
}
|
||||
getDeviceOwnerAdminLocked().isNetworkLoggingEnabled = enabled;
|
||||
saveSettingsLocked(mInjector.userHandleGetCallingUserId());
|
||||
|
||||
setNetworkLoggingActiveInternal(enabled);
|
||||
}
|
||||
|
||||
private synchronized void setNetworkLoggingActiveInternal(boolean active) {
|
||||
final long callingIdentity = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
if (active) {
|
||||
mNetworkLogger = new NetworkLogger(this, mInjector.getPackageManagerInternal());
|
||||
if (!mNetworkLogger.startNetworkLogging()) {
|
||||
mNetworkLogger = null;
|
||||
Slog.wtf(LOG_TAG, "Network logging could not be started due to the logging"
|
||||
+ " service not being available yet.");
|
||||
}
|
||||
} else {
|
||||
if (mNetworkLogger != null && !mNetworkLogger.stopNetworkLogging()) {
|
||||
mNetworkLogger = null;
|
||||
Slog.wtf(LOG_TAG, "Network logging could not be stopped due to the logging"
|
||||
+ " service not being available yet.");
|
||||
}
|
||||
mNetworkLogger = null;
|
||||
}
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkLoggingEnabled(ComponentName admin) {
|
||||
if (!mHasFeature) {
|
||||
return false;
|
||||
}
|
||||
Preconditions.checkNotNull(admin);
|
||||
synchronized (this) {
|
||||
getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
|
||||
return isNetworkLoggingEnabledInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized boolean isNetworkLoggingEnabledInternal() {
|
||||
ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
|
||||
return (deviceOwner != null) && deviceOwner.isNetworkLoggingEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.net.IIpConnectivityMetrics;
|
||||
import android.net.INetdEventCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.ServiceThread;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class for managing network logging.
|
||||
* This class is not thread-safe, callers should synchronize access.
|
||||
*/
|
||||
final class NetworkLogger {
|
||||
|
||||
private static final String TAG = NetworkLogger.class.getSimpleName();
|
||||
|
||||
private final DevicePolicyManagerService mDpm;
|
||||
private final PackageManagerInternal mPm;
|
||||
|
||||
private IIpConnectivityMetrics mIpConnectivityMetrics;
|
||||
private boolean mIsLoggingEnabled;
|
||||
|
||||
private final INetdEventCallback mNetdEventCallback = new INetdEventCallback.Stub() {
|
||||
@Override
|
||||
public void onDnsEvent(String hostname, String[] ipAddresses, int ipAddressesCount,
|
||||
long timestamp, int uid) {
|
||||
if (!mIsLoggingEnabled) {
|
||||
return;
|
||||
}
|
||||
// TODO(mkarpinski): send msg with data to Handler
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectEvent(String ipAddr, int port, long timestamp, int uid) {
|
||||
if (!mIsLoggingEnabled) {
|
||||
return;
|
||||
}
|
||||
// TODO(mkarpinski): send msg with data to Handler
|
||||
}
|
||||
};
|
||||
|
||||
NetworkLogger(DevicePolicyManagerService dpm, PackageManagerInternal pm) {
|
||||
mDpm = dpm;
|
||||
mPm = pm;
|
||||
}
|
||||
|
||||
private boolean checkIpConnectivityMetricsService() {
|
||||
if (mIpConnectivityMetrics != null) {
|
||||
return true;
|
||||
}
|
||||
final IIpConnectivityMetrics service = mDpm.mInjector.getIIpConnectivityMetrics();
|
||||
if (service == null) {
|
||||
return false;
|
||||
}
|
||||
mIpConnectivityMetrics = service;
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean startNetworkLogging() {
|
||||
Log.d(TAG, "Starting network logging.");
|
||||
if (!checkIpConnectivityMetricsService()) {
|
||||
// the IIpConnectivityMetrics service should have been present at this point
|
||||
Slog.wtf(TAG, "Failed to register callback with IIpConnectivityMetrics.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (mIpConnectivityMetrics.registerNetdEventCallback(mNetdEventCallback)) {
|
||||
// TODO(mkarpinski): start a new ServiceThread, instantiate a Handler etc.
|
||||
mIsLoggingEnabled = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Slog.wtf(TAG, "Failed to make remote calls to register the callback", re);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean stopNetworkLogging() {
|
||||
Log.d(TAG, "Stopping network logging");
|
||||
// stop the logging regardless of whether we failed to unregister listener
|
||||
mIsLoggingEnabled = false;
|
||||
try {
|
||||
if (!checkIpConnectivityMetricsService()) {
|
||||
// the IIpConnectivityMetrics service should have been present at this point
|
||||
Slog.wtf(TAG, "Failed to unregister callback with IIpConnectivityMetrics.");
|
||||
// logging is forcefully disabled even if unregistering fails
|
||||
return true;
|
||||
}
|
||||
return mIpConnectivityMetrics.unregisterNetdEventCallback();
|
||||
} catch (RemoteException re) {
|
||||
Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re);
|
||||
} finally {
|
||||
// TODO(mkarpinski): quitSafely() the Handler
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.net.Network;
|
||||
import android.net.metrics.DnsEvent;
|
||||
import android.net.metrics.INetdEventListener;
|
||||
import android.net.metrics.IpConnectivityLog;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Before;
|
||||
@@ -157,9 +158,13 @@ public class NetdEventListenerServiceTest extends TestCase {
|
||||
}
|
||||
|
||||
void log(int netId, int[] latencies) {
|
||||
for (int l : latencies) {
|
||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null, 0,
|
||||
0);
|
||||
try {
|
||||
for (int l : latencies) {
|
||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
|
||||
0, 0);
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user