Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package android.net;
     17 
     18 import android.annotation.SystemApi;
     19 import android.app.PendingIntent;
     20 import android.os.Bundle;
     21 import android.os.Parcelable;
     22 import android.os.RemoteException;
     23 import android.os.ServiceManager;
     24 import android.util.Log;
     25 
     26 /** {@hide} */
     27 @SystemApi
     28 public class ConnectivityMetricsLogger {
     29     private static String TAG = "ConnectivityMetricsLogger";
     30     private static final boolean DBG = true;
     31 
     32     public static final String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger";
     33 
     34     // Component Tags
     35     public static final int COMPONENT_TAG_CONNECTIVITY = 0;
     36     public static final int COMPONENT_TAG_BLUETOOTH = 1;
     37     public static final int COMPONENT_TAG_WIFI = 2;
     38     public static final int COMPONENT_TAG_TELECOM = 3;
     39     public static final int COMPONENT_TAG_TELEPHONY = 4;
     40 
     41     public static final int NUMBER_OF_COMPONENTS = 5;
     42 
     43     // Event Tag
     44     public static final int TAG_SKIPPED_EVENTS = -1;
     45 
     46     public static final String DATA_KEY_EVENTS_COUNT = "count";
     47 
     48     private IConnectivityMetricsLogger mService;
     49 
     50     private long mServiceUnblockedTimestampMillis = 0;
     51     private int mNumSkippedEvents = 0;
     52 
     53     public ConnectivityMetricsLogger() {
     54         mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService(
     55                 CONNECTIVITY_METRICS_LOGGER_SERVICE));
     56     }
     57 
     58     public void logEvent(long timestamp, int componentTag, int eventTag, Parcelable data) {
     59         if (mService == null) {
     60             if (DBG) {
     61                 Log.d(TAG, "logEvent(" + componentTag + "," + eventTag + ") Service not ready");
     62             }
     63             return;
     64         }
     65 
     66         if (mServiceUnblockedTimestampMillis > 0) {
     67             if (System.currentTimeMillis() < mServiceUnblockedTimestampMillis) {
     68                 // Service is throttling events.
     69                 // Don't send new events because they will be dropped.
     70                 mNumSkippedEvents++;
     71                 return;
     72             }
     73         }
     74 
     75         ConnectivityMetricsEvent skippedEventsEvent = null;
     76         if (mNumSkippedEvents > 0) {
     77             // Log number of skipped events
     78             Bundle b = new Bundle();
     79             b.putInt(DATA_KEY_EVENTS_COUNT, mNumSkippedEvents);
     80             skippedEventsEvent = new ConnectivityMetricsEvent(mServiceUnblockedTimestampMillis,
     81                     componentTag, TAG_SKIPPED_EVENTS, b);
     82 
     83             mServiceUnblockedTimestampMillis = 0;
     84         }
     85 
     86         ConnectivityMetricsEvent event = new ConnectivityMetricsEvent(timestamp, componentTag,
     87                 eventTag, data);
     88 
     89         try {
     90             long result;
     91             if (skippedEventsEvent == null) {
     92                 result = mService.logEvent(event);
     93             } else {
     94                 result = mService.logEvents(new ConnectivityMetricsEvent[]
     95                         {skippedEventsEvent, event});
     96             }
     97 
     98             if (result == 0) {
     99                 mNumSkippedEvents = 0;
    100             } else {
    101                 mNumSkippedEvents++;
    102                 if (result > 0) { // events are throttled
    103                     mServiceUnblockedTimestampMillis = result;
    104                 }
    105             }
    106         } catch (RemoteException e) {
    107             Log.e(TAG, "Error logging event " + e.getMessage());
    108         }
    109     }
    110 
    111     /**
    112      * Retrieve events
    113      *
    114      * @param reference of the last event previously returned. The function will return
    115      *                  events following it.
    116      *                  If 0 then all events will be returned.
    117      *                  After the function call it will contain reference of the
    118      *                  last returned event.
    119      * @return events
    120      */
    121     public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) {
    122         try {
    123             return mService.getEvents(reference);
    124         } catch (RemoteException ex) {
    125             Log.e(TAG, "IConnectivityMetricsLogger.getEvents: " + ex);
    126             return null;
    127         }
    128     }
    129 
    130     /**
    131      * Register PendingIntent which will be sent when new events are ready to be retrieved.
    132      */
    133     public boolean register(PendingIntent newEventsIntent) {
    134         try {
    135             return mService.register(newEventsIntent);
    136         } catch (RemoteException ex) {
    137             Log.e(TAG, "IConnectivityMetricsLogger.register: " + ex);
    138             return false;
    139         }
    140     }
    141 
    142     public boolean unregister(PendingIntent newEventsIntent) {
    143         try {
    144             mService.unregister(newEventsIntent);
    145         } catch (RemoteException ex) {
    146             Log.e(TAG, "IConnectivityMetricsLogger.unregister: " + ex);
    147             return false;
    148         }
    149 
    150         return true;
    151     }
    152 }
    153