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

Commit e2d7cd93 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge "Add ipconnectivity.proto to services jar am: 50a84c62 am: 446a3847"...

Merge "Add ipconnectivity.proto to services jar am: 50a84c62 am: 446a3847" into nyc-mr1-dev-plus-aosp
parents 351c7e5a 7b617182
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ LOCAL_AIDL_INCLUDES := system/netd/server/binder

LOCAL_SRC_FILES += \
    $(call all-java-files-under,java) \
    $(call all-proto-files-under, proto) \
    java/com/android/server/EventLogTags.logtags \
    java/com/android/server/am/EventLogTags.logtags \
    ../../../../system/netd/server/binder/android/net/INetd.aidl \
@@ -18,6 +19,7 @@ LOCAL_AIDL_INCLUDES += \

LOCAL_JAVA_LIBRARIES := services.net telephony-common
LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
LOCAL_PROTOC_OPTIMIZE_TYPE := nano

ifneq ($(INCREMENTAL_BUILDS),)
    LOCAL_PROGUARD_ENABLED := disabled
+257 −0
Original line number Diff line number Diff line
/*
 * 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.connectivity;

import android.net.ConnectivityMetricsEvent;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.ApfStats;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.DhcpClientEvent;
import android.net.metrics.DhcpErrorEvent;
import android.net.metrics.DnsEvent;
import android.net.metrics.IpManagerEvent;
import android.net.metrics.IpReachabilityEvent;
import android.net.metrics.NetworkEvent;
import android.net.metrics.RaEvent;
import android.net.metrics.ValidationProbeEvent;
import android.os.Parcelable;
import com.android.server.connectivity.metrics.IpConnectivityLogClass;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityEvent;
import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
import static com.android.server.connectivity.metrics.IpConnectivityLogClass.NetworkId;

/** {@hide} */
final public class IpConnectivityEventBuilder {
    private IpConnectivityEventBuilder() {
    }

    public static byte[] serialize(int dropped, List<ConnectivityMetricsEvent> events)
            throws IOException {
        final IpConnectivityLog log = new IpConnectivityLog();
        log.events = toProto(events);
        log.droppedEvents = dropped;
        return IpConnectivityLog.toByteArray(log);
    }

    public static IpConnectivityEvent[] toProto(List<ConnectivityMetricsEvent> eventsIn) {
        final ArrayList<IpConnectivityEvent> eventsOut = new ArrayList<>(eventsIn.size());
        for (ConnectivityMetricsEvent in : eventsIn) {
            final IpConnectivityEvent out = toProto(in);
            if (out == null) {
                continue;
            }
            eventsOut.add(out);
        }
        return eventsOut.toArray(new IpConnectivityEvent[eventsOut.size()]);
    }

    public static IpConnectivityEvent toProto(ConnectivityMetricsEvent ev) {
        final IpConnectivityEvent out = new IpConnectivityEvent();
        if (!setEvent(out, ev.data)) {
            return null;
        }
        out.timeMs = ev.timestamp;
        return out;
    }

    private static boolean setEvent(IpConnectivityEvent out, Parcelable in) {
        if (in instanceof DhcpErrorEvent) {
            setDhcpErrorEvent(out, (DhcpErrorEvent) in);
            return true;
        }

        if (in instanceof DhcpClientEvent) {
            setDhcpClientEvent(out, (DhcpClientEvent) in);
            return true;
        }

        if (in instanceof DnsEvent) {
            setDnsEvent(out, (DnsEvent) in);
            return true;
        }

        if (in instanceof IpManagerEvent) {
            setIpManagerEvent(out, (IpManagerEvent) in);
            return true;
        }

        if (in instanceof IpReachabilityEvent) {
            setIpReachabilityEvent(out, (IpReachabilityEvent) in);
            return true;
        }

        if (in instanceof DefaultNetworkEvent) {
            setDefaultNetworkEvent(out, (DefaultNetworkEvent) in);
            return true;
        }

        if (in instanceof NetworkEvent) {
            setNetworkEvent(out, (NetworkEvent) in);
            return true;
        }

        if (in instanceof ValidationProbeEvent) {
            setValidationProbeEvent(out, (ValidationProbeEvent) in);
            return true;
        }

        if (in instanceof ApfProgramEvent) {
            setApfProgramEvent(out, (ApfProgramEvent) in);
            return true;
        }

        if (in instanceof ApfStats) {
            setApfStats(out, (ApfStats) in);
            return true;
        }

        if (in instanceof RaEvent) {
            setRaEvent(out, (RaEvent) in);
            return true;
        }

        return false;
    }

    private static void setDhcpErrorEvent(IpConnectivityEvent out, DhcpErrorEvent in) {
        out.dhcpEvent = new IpConnectivityLogClass.DHCPEvent();
        out.dhcpEvent.ifName = in.ifName;
        out.dhcpEvent.errorCode = in.errorCode;
    }

    private static void setDhcpClientEvent(IpConnectivityEvent out, DhcpClientEvent in) {
        out.dhcpEvent = new IpConnectivityLogClass.DHCPEvent();
        out.dhcpEvent.ifName = in.ifName;
        out.dhcpEvent.stateTransition = in.msg;
        out.dhcpEvent.durationMs = in.durationMs;
    }

    private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) {
        out.dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch();
        out.dnsLookupBatch.networkId = netIdOf(in.netId);
        out.dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes);
        out.dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes);
        out.dnsLookupBatch.latenciesMs = in.latenciesMs;
    }

    private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) {
        out.ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent();
        out.ipProvisioningEvent.ifName = in.ifName;
        out.ipProvisioningEvent.eventType = in.eventType;
        out.ipProvisioningEvent.latencyMs = (int) in.durationMs;
    }

    private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) {
        out.ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent();
        out.ipReachabilityEvent.ifName = in.ifName;
        out.ipReachabilityEvent.eventType = in.eventType;
    }

    private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) {
        out.defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent();
        out.defaultNetworkEvent.networkId = netIdOf(in.netId);
        out.defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId);
        out.defaultNetworkEvent.transportTypes = in.transportTypes;
        out.defaultNetworkEvent.previousNetworkIpSupport = ipSupportOf(in);
    }

    private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) {
        out.networkEvent = new IpConnectivityLogClass.NetworkEvent();
        out.networkEvent.networkId = netIdOf(in.netId);
        out.networkEvent.eventType = in.eventType;
        out.networkEvent.latencyMs = (int) in.durationMs;
    }

    private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) {
        out.validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent();
        out.validationProbeEvent.networkId = netIdOf(in.netId);
        out.validationProbeEvent.latencyMs = (int) in.durationMs;
        out.validationProbeEvent.probeType = in.probeType;
        out.validationProbeEvent.probeResult = in.returnCode;
    }

    private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) {
        out.apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent();
        out.apfProgramEvent.lifetime = in.lifetime;
        out.apfProgramEvent.filteredRas = in.filteredRas;
        out.apfProgramEvent.currentRas = in.currentRas;
        out.apfProgramEvent.programLength = in.programLength;
        if (isBitSet(in.flags, ApfProgramEvent.FLAG_MULTICAST_FILTER_ON)) {
            out.apfProgramEvent.dropMulticast = true;
        }
        if (isBitSet(in.flags, ApfProgramEvent.FLAG_HAS_IPV4_ADDRESS)) {
            out.apfProgramEvent.hasIpv4Addr = true;
        }
    }

    private static void setApfStats(IpConnectivityEvent out, ApfStats in) {
        out.apfStatistics = new IpConnectivityLogClass.ApfStatistics();
        out.apfStatistics.durationMs = in.durationMs;
        out.apfStatistics.receivedRas = in.receivedRas;
        out.apfStatistics.matchingRas = in.matchingRas;
        out.apfStatistics.droppedRas = in.droppedRas;
        out.apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas;
        out.apfStatistics.parseErrors = in.parseErrors;
        out.apfStatistics.programUpdates = in.programUpdates;
        out.apfStatistics.maxProgramSize = in.maxProgramSize;
    }

    private static void setRaEvent(IpConnectivityEvent out, RaEvent in) {
        out.raEvent = new IpConnectivityLogClass.RaEvent();
        out.raEvent.routerLifetime = in.routerLifetime;
        out.raEvent.prefixValidLifetime = in.prefixValidLifetime;
        out.raEvent.prefixPreferredLifetime = in.prefixPreferredLifetime;
        out.raEvent.routeInfoLifetime = in.routeInfoLifetime;
        out.raEvent.rdnssLifetime = in.rdnssLifetime;
        out.raEvent.dnsslLifetime = in.dnsslLifetime;
    }

    private static int[] bytesToInts(byte[] in) {
        final int[] out = new int[in.length];
        for (int i = 0; i < in.length; i++) {
            out[i] = in[i] & 0xFF;
        }
        return out;
    }

    private static NetworkId netIdOf(int netid) {
        final NetworkId ni = new NetworkId();
        ni.networkId = netid;
        return ni;
    }

    private static int ipSupportOf(DefaultNetworkEvent in) {
        if (in.prevIPv4 && in.prevIPv6) {
            return IpConnectivityLogClass.DefaultNetworkEvent.DUAL;
        }
        if (in.prevIPv6) {
            return IpConnectivityLogClass.DefaultNetworkEvent.IPV6;
        }
        if (in.prevIPv4) {
            return IpConnectivityLogClass.DefaultNetworkEvent.IPV4;
        }
        return IpConnectivityLogClass.DefaultNetworkEvent.NONE;
    }

    private static boolean isBitSet(int flags, int bit) {
        return (flags & (1 << bit)) != 0;
    }
}
+274 −0
Original line number Diff line number Diff line
// LINT: LEGACY_NAMES
syntax = "proto2";

package clearcut.connectivity;

option java_package = "com.android.server.connectivity.metrics";
option java_outer_classname = "IpConnectivityLogClass";

// NetworkId represents the id given by the system to a physical network on the
// Android device. It is used to relates events to each other for devices with
// multiple networks (WiFi, 4G, ...).
message NetworkId {
  // Every network gets assigned a network_id on creation based on order of
  // creation. Thus network_id N is assigned to the network created directly
  // after network N-1. Thus there is no PII involved here. Zero means no
  // network. The value 0 is never assigned to a network.
  optional int32 network_id = 1;
};

// Logs changes in the system default network. Changes can be 1) acquiring a
// default network with no previous default, 2) a switch of the system default
// network to a new default network, 3) a loss of the system default network.
// This message is associated to android.net.metrics.DefaultNetworkEvent.
message DefaultNetworkEvent {
  // A value of 0 means this is a loss of the system default network.
  optional NetworkId network_id = 1;

  // A value of 0 means there was no previous default network.
  optional NetworkId previous_network_id = 2;

  // Whether the network supports IPv4, IPv6, or both.
  enum IPSupport {
    NONE = 0;
    IPV4 = 1;
    IPV6 = 2;
    DUAL = 3;
  };

  // Best available information about IP support of the previous network when
  // disconnecting or switching to a new default network.
  optional IPSupport previous_network_ip_support = 3;

  // The transport types of the new default network, represented by
  // TRANSPORT_* constants as defined in NetworkCapabilities.
  repeated int32 transport_types = 4;
};

// Logs IpReachabilityMonitor probe events and NUD_FAILED events.
// This message is associated to android.net.metrics.IpReachabilityEvent.
message IpReachabilityEvent {
  // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
  optional string if_name = 1;

  // The event type code of the probe, represented by constants defined in
  // android.net.metrics.IpReachabilityEvent.
  optional int32 event_type = 2;
};

// Logs NetworkMonitor and ConnectivityService events related to the state of
// a network: connection, evaluation, validation, lingering, and disconnection.
// This message is associated to android.net.metrics.NetworkEvent.
message NetworkEvent {
  // The id of the network on which this event happened.
  optional NetworkId network_id = 1;

  // The type of network event, represented by NETWORK_* constants defined in
  // android.net.metrics.NetworkEvent.
  optional int32 event_type = 2;

  // Only valid after finishing evaluating a network for Internet connectivity.
  // The time it took for this evaluation to complete.
  optional int32 latency_ms = 3;
}

// Logs individual captive portal probing events that are performed when
// evaluating or reevaluating networks for Internet connectivity.
// This message is associated to android.net.metrics.ValidationProbeEvent.
message ValidationProbeEvent {
  // The id of the network for which the probe was sent.
  optional NetworkId network_id = 1;

  // The time it took for that probe to complete or time out.
  optional int32 latency_ms = 2;

  // The type of portal probe, represented by PROBE_* constants defined in
  // android.net.metrics.ValidationProbeEvent.
  optional int32 probe_type = 3;

  // The http code result of the probe test.
  optional int32 probe_result = 4;
}

// Logs DNS lookup latencies. Repeated fields must have the same length.
// This message is associated to android.net.metrics.DnsEvent.
message DNSLookupBatch {
  // The id of the network on which the DNS lookups took place.
  optional NetworkId network_id = 1;

  // The types of the DNS lookups, as defined in android.net.metrics.DnsEvent.
  repeated int32 event_types = 2;

  // The return values of the DNS resolver for each DNS lookups.
  repeated int32 return_codes = 3;

  // The time it took for each DNS lookups to complete.
  repeated int32 latencies_ms = 4;
};

// Represents a DHCP event on a single interface, which can be a DHCPClient
// state transition or a response packet parsing error.
// This message is associated to android.net.metrics.DhcpClientEvent and
// android.net.metrics.DhcpErrorEvent.
message DHCPEvent {
  // The interface name (wlan, rmnet, lo, ...) on which the event happened.
  optional string if_name = 1;

  oneof value {
    // The name of a state in the DhcpClient state machine, represented by
    // the inner classes of android.net.dhcp.DhcpClient.
    string state_transition = 2;

    // The error code of a DHCP error, represented by constants defined in
    // android.net.metrics.DhcpErrorEvent.
    int32 error_code = 3;
  }

  // Lifetime duration in milliseconds of a DhcpClient state, or transition
  // time in milliseconds between specific pairs of DhcpClient's states.
  // Only populated when state_transition is populated.
  optional int32 duration_ms = 4;
}

// Represents the generation of an Android Packet Filter program.
message ApfProgramEvent {
  // Lifetime of the program in seconds.
  optional int64 lifetime = 1;

  // Number of RAs filtered by the APF program.
  optional int32 filtered_ras = 2;

  // Total number of RAs to filter currently tracked by ApfFilter. Can be more
  // than filtered_ras if all available program size was exhausted.
  optional int32 current_ras = 3;

  // Length of the APF program in bytes.
  optional int32 program_length = 4;

  // True if the APF program is dropping multicast and broadcast traffic.
  optional bool drop_multicast = 5;

  // True if the interface on which APF runs has an IPv4 address.
  optional bool has_ipv4_addr = 6;
}

// Represents Router Advertisement listening statistics for an interface with
// Android Packet Filter enabled.
message ApfStatistics {
  // The time interval in milliseconds these stastistics cover.
  optional int64 duration_ms = 1;

  // The total number of received RAs.
  optional int32 received_ras = 2;

  // The total number of received RAs that matched a known RA.
  optional int32 matching_ras = 3;

  // The total number of received RAs ignored due to the MAX_RAS limit.
  optional int32 dropped_ras = 5;

  // The total number of received RAs with an effective lifetime of 0 seconds.
  // Effective lifetime for APF is the minimum of all lifetimes in a RA.
  optional int32 zero_lifetime_ras = 6;

  // The total number of received RAs that could not be parsed.
  optional int32 parse_errors = 7;

  // The total number of APF program updates triggered by an RA reception.
  optional int32 program_updates = 8;

  // The maximum APF program size in byte advertised by hardware.
  optional int32 max_program_size = 9;
}

// Represents the reception of a Router Advertisement packet for an interface
// with Android Packet Filter enabled.
message RaEvent {
  // All lifetime values are expressed in seconds. The default value for an
  // option lifetime that was not present in the RA option list is -1.
  // The lifetime of an option (e.g., the Prefix Information Option) is the
  // minimum lifetime of all such options in the packet.

  // The value of the router lifetime in the RA packet.
  optional int64 router_lifetime = 1;

  // Prefix valid lifetime from the prefix information option.
  optional int64 prefix_valid_lifetime = 2;

  // Prefix preferred lifetime from the prefix information option.
  optional int64 prefix_preferred_lifetime = 3;

  // Route info lifetime.
  optional int64 route_info_lifetime = 4;

  // Recursive DNS server lifetime.
  optional int64 rdnss_lifetime = 5;

  // DNS search list lifetime.
  optional int64 dnssl_lifetime = 6;
}

// Represents an IP provisioning event in IpManager and how long the
// provisioning action took.
// This message is associated to android.net.metrics.IpManagerEvent.
message IpProvisioningEvent {
  // The interface name (wlan, rmnet, lo, ...) on which the probe was sent.
  optional string if_name = 1;

  // The code of the IP provisioning event, represented by constants defined in
  // android.net.metrics.IpManagerEvent.
  optional int32 event_type = 2;

  // The duration of the provisioning action that resulted in this event.
  optional int32 latency_ms = 3;
}

// Represents one of the IP connectivity event defined in this file.
// Next tag: 12
message IpConnectivityEvent {
  // Time in ms when the event was recorded.
  optional int64 time_ms = 1;

  // Event type.
  oneof event {

    // An event about the system default network.
    DefaultNetworkEvent default_network_event = 2;

    // An IP reachability probe event.
    IpReachabilityEvent ip_reachability_event = 3;

    // A network lifecycle event.
    NetworkEvent network_event = 4;

    // A batch of DNS lookups.
    DNSLookupBatch dns_lookup_batch = 5;

    // A DHCP client event or DHCP receive error.
    DHCPEvent dhcp_event = 6;

    // An IP provisioning event.
    IpProvisioningEvent ip_provisioning_event = 7;

    // A network validation probe event.
    ValidationProbeEvent validation_probe_event = 8;

    // An Android Packet Filter program event.
    ApfProgramEvent apf_program_event = 9;

    // An Android Packet Filter statistics event.
    ApfStatistics apf_statistics = 10;

    // An RA packet reception event.
    RaEvent ra_event = 11;
  };
};

// The information about IP connectivity events.
message IpConnectivityLog {
  // An array of IP connectivity events.
  repeated IpConnectivityEvent events = 1;

  // The number of events that had to be dropped due to a full buffer.
  optional int32 dropped_events = 2;
};
+359 −0

File added.

Preview size limit exceeded, changes collapsed.

+120 −0
Original line number Diff line number Diff line
/*
 * 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.connectivity;

import android.net.ConnectivityMetricsEvent;
import android.net.ConnectivityMetricsLogger;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

abstract public class MetricsTestUtil {
    private MetricsTestUtil() {
    }

    static ConnectivityMetricsEvent ipEv(Parcelable p) {
        return ev(ConnectivityMetricsLogger.COMPONENT_TAG_CONNECTIVITY, p);
    }

    static ConnectivityMetricsEvent telephonyEv() {
        return ev(ConnectivityMetricsLogger.COMPONENT_TAG_TELEPHONY, new Bundle());
    }

    static ConnectivityMetricsEvent ev(int tag, Parcelable p) {
        return new ConnectivityMetricsEvent(1L, tag, 0, p);
    }

    // Utiliy interface for describing the content of a Parcel. This relies on
    // the implementation defails of Parcelable and on the fact that the fully
    // qualified Parcelable class names are written as string in the Parcels.
    interface ParcelField {
        void write(Parcel p);
    }

    static ConnectivityMetricsEvent describeIpEvent(ParcelField... fs) {
        Parcel p = Parcel.obtain();
        for (ParcelField f : fs) {
            f.write(p);
        }
        p.setDataPosition(0);
        return ipEv(p.readParcelable(ClassLoader.getSystemClassLoader()));
    }

    static ParcelField aType(Class<?> c) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeString(c.getName());
            }
        };
    }

    static ParcelField aBool(boolean b) {
        return aByte((byte) (b ? 1 : 0));
    }

    static ParcelField aByte(byte b) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeByte(b);
            }
        };
    }

    static ParcelField anInt(int i) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeInt(i);
            }
        };
    }

    static ParcelField aLong(long l) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeLong(l);
            }
        };
    }

    static ParcelField aString(String s) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeString(s);
            }
        };
    }

    static ParcelField aByteArray(byte... ary) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeByteArray(ary);
            }
        };
    }

    static ParcelField anIntArray(int... ary) {
        return new ParcelField() {
            public void write(Parcel p) {
                p.writeIntArray(ary);
            }
        };
    }

    static byte b(int i) {
        return (byte) i;
    }
}