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/IIpConnectivityMetrics.aidl \
|
||||||
core/java/android/net/IEthernetManager.aidl \
|
core/java/android/net/IEthernetManager.aidl \
|
||||||
core/java/android/net/IEthernetServiceListener.aidl \
|
core/java/android/net/IEthernetServiceListener.aidl \
|
||||||
|
core/java/android/net/INetdEventCallback.aidl \
|
||||||
core/java/android/net/INetworkManagementEventObserver.aidl \
|
core/java/android/net/INetworkManagementEventObserver.aidl \
|
||||||
core/java/android/net/INetworkPolicyListener.aidl \
|
core/java/android/net/INetworkPolicyListener.aidl \
|
||||||
core/java/android/net/INetworkPolicyManager.aidl \
|
core/java/android/net/INetworkPolicyManager.aidl \
|
||||||
|
|||||||
@@ -6609,4 +6609,46 @@ public class DevicePolicyManager {
|
|||||||
throw re.rethrowFromSystemServer();
|
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);
|
void setBackupServiceEnabled(in ComponentName admin, boolean enabled);
|
||||||
boolean isBackupServiceEnabled(in ComponentName admin);
|
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.os.Parcelable;
|
||||||
import android.net.ConnectivityMetricsEvent;
|
import android.net.ConnectivityMetricsEvent;
|
||||||
|
import android.net.INetdEventCallback;
|
||||||
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
interface IIpConnectivityMetrics {
|
interface IIpConnectivityMetrics {
|
||||||
@@ -27,4 +28,13 @@ interface IIpConnectivityMetrics {
|
|||||||
* or -1 if the event was dropped due to rate limiting.
|
* or -1 if the event was dropped due to rate limiting.
|
||||||
*/
|
*/
|
||||||
int logEvent(in ConnectivityMetricsEvent event);
|
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.content.Context;
|
||||||
import android.net.ConnectivityMetricsEvent;
|
import android.net.ConnectivityMetricsEvent;
|
||||||
import android.net.IIpConnectivityMetrics;
|
import android.net.IIpConnectivityMetrics;
|
||||||
|
import android.net.INetdEventCallback;
|
||||||
import android.net.metrics.ApfProgramEvent;
|
import android.net.metrics.ApfProgramEvent;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.os.Process;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@@ -260,6 +263,33 @@ final public class IpConnectivityMetrics extends SystemService {
|
|||||||
private void enforcePermission(String what) {
|
private void enforcePermission(String what) {
|
||||||
getContext().enforceCallingOrSelfPermission(what, "IpConnectivityMetrics");
|
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) -> {
|
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;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
|
import android.net.INetdEventCallback;
|
||||||
import android.net.NetworkRequest;
|
import android.net.NetworkRequest;
|
||||||
import android.net.metrics.DnsEvent;
|
import android.net.metrics.DnsEvent;
|
||||||
import android.net.metrics.INetdEventListener;
|
import android.net.metrics.INetdEventListener;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
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) {
|
public NetdEventListenerService(Context context) {
|
||||||
this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
|
this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
|
||||||
}
|
}
|
||||||
@@ -136,7 +153,8 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
|||||||
// Called concurrently by multiple binder threads.
|
// Called concurrently by multiple binder threads.
|
||||||
// This method must not block or perform long-running operations.
|
// This method must not block or perform long-running operations.
|
||||||
public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
|
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)",
|
maybeVerboseLog(String.format("onDnsEvent(%d, %d, %d, %d)",
|
||||||
netId, eventType, returnCode, latencyMs));
|
netId, eventType, returnCode, latencyMs));
|
||||||
|
|
||||||
@@ -146,14 +164,23 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
|
|||||||
mEventBatches.put(netId, batch);
|
mEventBatches.put(netId, batch);
|
||||||
}
|
}
|
||||||
batch.addResult((byte) eventType, (byte) returnCode, latencyMs);
|
batch.addResult((byte) eventType, (byte) returnCode, latencyMs);
|
||||||
|
|
||||||
|
if (mNetdEventCallback != null) {
|
||||||
|
mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount,
|
||||||
|
System.currentTimeMillis(), uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// Called concurrently by multiple binder threads.
|
// Called concurrently by multiple binder threads.
|
||||||
// This method must not block or perform long-running operations.
|
// This method must not block or perform long-running operations.
|
||||||
public synchronized void onConnectEvent(int netId, int latencyMs, String ipAddr, int port,
|
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));
|
maybeVerboseLog(String.format("onConnectEvent(%d, %d)", netId, latencyMs));
|
||||||
|
|
||||||
|
if (mNetdEventCallback != null) {
|
||||||
|
mNetdEventCallback.onConnectEvent(ipAddr, port, System.currentTimeMillis(), uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void dump(PrintWriter writer) {
|
public synchronized void dump(PrintWriter writer) {
|
||||||
|
|||||||
@@ -77,8 +77,10 @@ import android.graphics.Color;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.IAudioService;
|
import android.media.IAudioService;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.IIpConnectivityMetrics;
|
||||||
import android.net.ProxyInfo;
|
import android.net.ProxyInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.net.metrics.IpConnectivityLog;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@@ -352,6 +354,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
boolean mIsWatch;
|
boolean mIsWatch;
|
||||||
|
|
||||||
private final SecurityLogMonitor mSecurityLogMonitor;
|
private final SecurityLogMonitor mSecurityLogMonitor;
|
||||||
|
private NetworkLogger mNetworkLogger;
|
||||||
|
|
||||||
private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean();
|
private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean();
|
||||||
private final AtomicBoolean mRemoteBugreportSharingAccepted = 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,
|
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
|
||||||
getSendingUserId());
|
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)
|
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|
||||||
&& userHandle == mOwners.getDeviceOwnerUserId()
|
&& userHandle == mOwners.getDeviceOwnerUserId()
|
||||||
&& getDeviceOwnerRemoteBugreportUri() != null) {
|
&& 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_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
|
||||||
private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
|
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_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_ACCOUNT_TYPE = "account-type";
|
||||||
private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
|
private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
|
||||||
= "permitted-accessiblity-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 disableScreenCapture = false; // Can only be set by a device/profile owner.
|
||||||
boolean requireAutoTime = false; // Can only be set by a device owner.
|
boolean requireAutoTime = false; // Can only be set by a device owner.
|
||||||
boolean forceEphemeralUsers = 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;
|
ActiveAdmin parentAdmin;
|
||||||
final boolean isParent;
|
final boolean isParent;
|
||||||
@@ -851,6 +866,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
|
out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
|
||||||
out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
|
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) {
|
if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
|
||||||
out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
|
out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
|
||||||
out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
|
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)) {
|
} else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
|
||||||
forceEphemeralUsers = Boolean.parseBoolean(
|
forceEphemeralUsers = Boolean.parseBoolean(
|
||||||
parser.getAttributeValue(null, ATTR_VALUE));
|
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)) {
|
} else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
|
||||||
disabledKeyguardFeatures = Integer.parseInt(
|
disabledKeyguardFeatures = Integer.parseInt(
|
||||||
parser.getAttributeValue(null, ATTR_VALUE));
|
parser.getAttributeValue(null, ATTR_VALUE));
|
||||||
@@ -1277,6 +1300,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
pw.println(requireAutoTime);
|
pw.println(requireAutoTime);
|
||||||
pw.print(prefix); pw.print("forceEphemeralUsers=");
|
pw.print(prefix); pw.print("forceEphemeralUsers=");
|
||||||
pw.println(forceEphemeralUsers);
|
pw.println(forceEphemeralUsers);
|
||||||
|
pw.print(prefix); pw.print("isNetworkLoggingEnabled=");
|
||||||
|
pw.println(isNetworkLoggingEnabled);
|
||||||
pw.print(prefix); pw.print("disabledKeyguardFeatures=");
|
pw.print(prefix); pw.print("disabledKeyguardFeatures=");
|
||||||
pw.println(disabledKeyguardFeatures);
|
pw.println(disabledKeyguardFeatures);
|
||||||
pw.print(prefix); pw.print("crossProfileWidgetProviders=");
|
pw.print(prefix); pw.print("crossProfileWidgetProviders=");
|
||||||
@@ -1403,6 +1428,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
return mContext.getSystemService(NotificationManager.class);
|
return mContext.getSystemService(NotificationManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IIpConnectivityMetrics getIIpConnectivityMetrics() {
|
||||||
|
return (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface(
|
||||||
|
ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
PowerManagerInternal getPowerManagerInternal() {
|
PowerManagerInternal getPowerManagerInternal() {
|
||||||
return LocalServices.getService(PowerManagerInternal.class);
|
return LocalServices.getService(PowerManagerInternal.class);
|
||||||
}
|
}
|
||||||
@@ -9040,6 +9070,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
if (!isDeviceOwnerManagedSingleUserDevice()) {
|
if (!isDeviceOwnerManagedSingleUserDevice()) {
|
||||||
mInjector.securityLogSetLoggingEnabledProperty(false);
|
mInjector.securityLogSetLoggingEnabledProperty(false);
|
||||||
Slog.w(LOG_TAG, "Security logging turned off as it's no longer a single user device.");
|
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()) {
|
if (mOwners.hasDeviceOwner()) {
|
||||||
setBackupServiceEnabledInternal(false);
|
setBackupServiceEnabledInternal(false);
|
||||||
Slog.w(LOG_TAG, "Backup is off as it's a managed device that has more that one user.");
|
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.DnsEvent;
|
||||||
import android.net.metrics.INetdEventListener;
|
import android.net.metrics.INetdEventListener;
|
||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -157,9 +158,13 @@ public class NetdEventListenerServiceTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void log(int netId, int[] latencies) {
|
void log(int netId, int[] latencies) {
|
||||||
for (int l : latencies) {
|
try {
|
||||||
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null, 0,
|
for (int l : latencies) {
|
||||||
0);
|
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