1623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi/* 2623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * Copyright (C) 2016 The Android Open Source Project 3623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * 4623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * Licensed under the Apache License, Version 2.0 (the "License"); 5623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * you may not use this file except in compliance with the License. 6623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * You may obtain a copy of the License at 7623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * 8623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * http://www.apache.org/licenses/LICENSE-2.0 9623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * 10623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * Unless required by applicable law or agreed to in writing, software 11623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * distributed under the License is distributed on an "AS IS" BASIS, 12623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * See the License for the specific language governing permissions and 14623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * limitations under the License. 15623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi */ 16623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi 17623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichipackage android.net.metrics; 18623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi 19623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichiimport android.net.ConnectivityMetricsEvent; 2000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.net.IIpConnectivityMetrics; 21623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichiimport android.os.Parcelable; 22623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichiimport android.os.RemoteException; 2300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichiimport android.os.ServiceManager; 24623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichiimport android.util.Log; 253bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichiimport com.android.internal.annotations.VisibleForTesting; 26a365bace7a8e3e6da016531e26a6046a827acaa5Hugo Benichiimport com.android.internal.util.BitUtils; 273bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi 28623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi/** 2900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi * Class for logging IpConnectvity events with IpConnectivityMetrics 30623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * {@hide} 31623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi */ 3200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichipublic class IpConnectivityLog { 3300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi private static final String TAG = IpConnectivityLog.class.getSimpleName(); 3400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi private static final boolean DBG = false; 35623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi 36eab511b582cc00364dee7835534bb511719f9231Hugo Benichi public static final String SERVICE_NAME = "connmetrics"; 37eab511b582cc00364dee7835534bb511719f9231Hugo Benichi 3800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi private IIpConnectivityMetrics mService; 3900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi 403bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi public IpConnectivityLog() { 413bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi } 423bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi 433bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi @VisibleForTesting 4400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi public IpConnectivityLog(IIpConnectivityMetrics service) { 4500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi mService = service; 4600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi } 4700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi 4800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi private boolean checkLoggerService() { 4900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi if (mService != null) { 5000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi return true; 5100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi } 5200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi final IIpConnectivityMetrics service = 5300a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi IIpConnectivityMetrics.Stub.asInterface(ServiceManager.getService(SERVICE_NAME)); 5400a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi if (service == null) { 5500a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi return false; 5600a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi } 5700a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi // Two threads racing here will write the same pointer because getService 5800a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi // is idempotent once MetricsLoggerService is initialized. 5900a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi mService = service; 6000a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi return true; 613bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi } 623bba249c4711b10b2ba5335c7b6653dc570aae64Hugo Benichi 63623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi /** 64946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * Log a ConnectivityMetricsEvent. 65946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @param ev the event to log. If the event timestamp is 0, 66946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * the timestamp is set to the current time in milliseconds. 67623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi * @return true if the event was successfully logged. 68623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi */ 69946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi public boolean log(ConnectivityMetricsEvent ev) { 7090cbc5b44450e9806ce0227d125fe7d5107c7c4bHugo Benichi if (!checkLoggerService()) { 71623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi if (DBG) { 7200a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi Log.d(TAG, SERVICE_NAME + " service was not ready"); 73623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi } 74623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi return false; 75623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi } 76946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi if (ev.timestamp == 0) { 77946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi ev.timestamp = System.currentTimeMillis(); 78946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi } 79623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi try { 80ec27c4d9f33615be1f94d6bb5c5fd1358580ac05Hugo Benichi int left = mService.logEvent(ev); 8100a42d4c885bf7440c2677750ad8b10974b16d7fHugo Benichi return left >= 0; 82623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi } catch (RemoteException e) { 83623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi Log.e(TAG, "Error logging event", e); 84623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi return false; 85623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi } 86623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi } 87cfddd6879283860bb4d2cf2972ea086f585a37ecHugo Benichi 88946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi /** 89946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * Log an IpConnectivity event. 90946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @param timestamp is the epoch timestamp of the event in ms. 91946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * If the timestamp is 0, the timestamp is set to the current time in milliseconds. 92946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @param data is a Parcelable instance representing the event. 93946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @return true if the event was successfully logged. 94946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi */ 95946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi public boolean log(long timestamp, Parcelable data) { 96946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi ConnectivityMetricsEvent ev = makeEv(data); 97946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi ev.timestamp = timestamp; 98946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi return log(ev); 99946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi } 100946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi 101946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi /** 102946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * Log an IpConnectivity event. 103948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi * @param ifname the network interface associated with the event. 104948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi * @param data is a Parcelable instance representing the event. 105948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi * @return true if the event was successfully logged. 106948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi */ 107948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi public boolean log(String ifname, Parcelable data) { 108948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi ConnectivityMetricsEvent ev = makeEv(data); 109948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi ev.ifname = ifname; 110948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi return log(ev); 111948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi } 112948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi 113948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi /** 114948a85948dcccea4aaa9d70a74405308581b0925Hugo Benichi * Log an IpConnectivity event. 115f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * @param netid the id of the network associated with the event. 116f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * @param transports the current transports of the network associated with the event, as defined 117f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * in NetworkCapabilities. 118f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * @param data is a Parcelable instance representing the event. 119f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * @return true if the event was successfully logged. 120f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi */ 121a365bace7a8e3e6da016531e26a6046a827acaa5Hugo Benichi public boolean log(int netid, int[] transports, Parcelable data) { 122f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi ConnectivityMetricsEvent ev = makeEv(data); 123f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi ev.netId = netid; 124a365bace7a8e3e6da016531e26a6046a827acaa5Hugo Benichi ev.transports = BitUtils.packBits(transports); 125f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi return log(ev); 126f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi } 127f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi 128f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi /** 129f927f0c52e7df5b057e7d28888c3cfed164d241aHugo Benichi * Log an IpConnectivity event. 130946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @param data is a Parcelable instance representing the event. 131946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi * @return true if the event was successfully logged. 132946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi */ 133946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi public boolean log(Parcelable data) { 134946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi return log(makeEv(data)); 135946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi } 136946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi 137946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi private static ConnectivityMetricsEvent makeEv(Parcelable data) { 138946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi ConnectivityMetricsEvent ev = new ConnectivityMetricsEvent(); 139946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi ev.data = data; 140946b7e424e0e4d5bffc65ef405f32b966d192d3cHugo Benichi return ev; 141cfddd6879283860bb4d2cf2972ea086f585a37ecHugo Benichi } 142623ab7d7a6a7d948fa6338a3992b2680d0192427Hugo Benichi} 143