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

Commit d1cb256b authored by Pavel Zhamaitsiak's avatar Pavel Zhamaitsiak
Browse files

ConnectivityMetricsLogger: Switch to "pull" model

If subscriber is in external app, its process can be killed. This would
lead to loss of events. To avoid that, we will be storing events in the
logger service. Clients can periodically pull data from it.

Another option for client apps is to register PendingIntent which will be
sent when certain number of new events has been received.

If events are logged at unexpectedly high rate from particular component,
then throttling mechanism will activate and new events will be blocked for
some time from that component.

Change-Id: I710409626eb5a42bcd3fe8126eac6b756fa1ab8b
parent 3d09db6f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -190,7 +190,6 @@ LOCAL_SRC_FILES += \
	core/java/android/net/ICaptivePortal.aidl \
	core/java/android/net/IConnectivityManager.aidl \
	core/java/android/net/IConnectivityMetricsLogger.aidl \
	core/java/android/net/IConnectivityMetricsLoggerSubscriber.aidl \
	core/java/android/net/IEthernetManager.aidl \
	core/java/android/net/IEthernetServiceListener.aidl \
	core/java/android/net/INetworkManagementEventObserver.aidl \
+1 −0
Original line number Diff line number Diff line
@@ -17,3 +17,4 @@
package android.net;

parcelable ConnectivityMetricsEvent;
parcelable ConnectivityMetricsEvent.Reference;
+38 −0
Original line number Diff line number Diff line
@@ -79,4 +79,42 @@ public class ConnectivityMetricsEvent implements Parcelable {
        return String.format("ConnectivityMetricsEvent(%d, %d, %d)", timestamp,
                componentTag, eventTag);
    }

    /** {@hide} */
    public static class Reference implements Parcelable {

        public long value;

        public Reference(long ref) {
            this.value = ref;
        }

        /** Implement the Parcelable interface */
        public static final Parcelable.Creator<Reference> CREATOR
                = new Parcelable.Creator<Reference> (){
            public Reference createFromParcel(Parcel source) {
                return new Reference(source.readLong());
            }

            public Reference[] newArray(int size) {
                return new Reference[size];
            }
        };

        /** Implement the Parcelable interface */
        @Override
        public int describeContents() {
            return 0;
        }

        /** Implement the Parcelable interface */
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(value);
        }

        public void readFromParcel(Parcel in) {
            value = in.readLong();
        }
    }
}
+60 −10
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package android.net;

import android.os.Bundle;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -28,14 +29,24 @@ public class ConnectivityMetricsLogger {
    public static final String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger";

    // Component Tags
    public static final int COMPONENT_TAG_CONNECTIVITY = 1;
    public static final int COMPONENT_TAG_BLUETOOTH = 2;
    public static final int COMPONENT_TAG_WIFI = 3;
    public static final int COMPONENT_TAG_TELECOM = 4;
    public static final int COMPONENT_TAG_TELEPHONY = 5;
    public static final int COMPONENT_TAG_CONNECTIVITY = 0;
    public static final int COMPONENT_TAG_BLUETOOTH = 1;
    public static final int COMPONENT_TAG_WIFI = 2;
    public static final int COMPONENT_TAG_TELECOM = 3;
    public static final int COMPONENT_TAG_TELEPHONY = 4;

    public static final int NUMBER_OF_COMPONENTS = 5;

    // Event Tag
    public static final int TAG_SKIPPED_EVENTS = -1;

    public static final String DATA_KEY_EVENTS_COUNT = "count";

    private IConnectivityMetricsLogger mService;

    private long mServiceUnblockedTimestampMillis = 0;
    private int mNumSkippedEvents = 0;

    public ConnectivityMetricsLogger() {
        mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService(
                CONNECTIVITY_METRICS_LOGGER_SERVICE));
@@ -46,12 +57,51 @@ public class ConnectivityMetricsLogger {
            if (DBG) {
                Log.d(TAG, "logEvent(" + componentTag + "," + eventTag + ") Service not ready");
            }
        } else {
            return;
        }

        if (mServiceUnblockedTimestampMillis > 0) {
            if (System.currentTimeMillis() < mServiceUnblockedTimestampMillis) {
                // Service is throttling events.
                // Don't send new events because they will be dropped.
                mNumSkippedEvents++;
                return;
            }
        }

        ConnectivityMetricsEvent skippedEventsEvent = null;
        if (mNumSkippedEvents > 0) {
            // Log number of skipped events
            Bundle b = new Bundle();
            b.putInt(DATA_KEY_EVENTS_COUNT, mNumSkippedEvents);
            skippedEventsEvent = new ConnectivityMetricsEvent(mServiceUnblockedTimestampMillis,
                    componentTag, TAG_SKIPPED_EVENTS, b);

            mServiceUnblockedTimestampMillis = 0;
        }

        ConnectivityMetricsEvent event = new ConnectivityMetricsEvent(timestamp, componentTag,
                eventTag, data);

        try {
                mService.logEvent(new ConnectivityMetricsEvent(timestamp, componentTag, eventTag, data));
            long result;
            if (skippedEventsEvent == null) {
                result = mService.logEvent(event);
            } else {
                result = mService.logEvents(new ConnectivityMetricsEvent[]
                        {skippedEventsEvent, event});
            }

            if (result == 0) {
                mNumSkippedEvents = 0;
            } else {
                mNumSkippedEvents++;
                if (result > 0) { // events are throttled
                    mServiceUnblockedTimestampMillis = result;
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Error logging event " + e.getMessage());
        }
    }
}
}
+18 −5
Original line number Diff line number Diff line
@@ -16,15 +16,28 @@

package android.net;

import android.app.PendingIntent;
import android.net.ConnectivityMetricsEvent;
import android.net.IConnectivityMetricsLoggerSubscriber;

/** {@hide} */
interface IConnectivityMetricsLogger {

    void logEvent(in ConnectivityMetricsEvent event);
    void logEvents(in ConnectivityMetricsEvent[] events);
    /**
     * @return 0 on success
     *        <0 if error happened
     *        >0 timestamp after which new events will be accepted
     */
    long logEvent(in ConnectivityMetricsEvent event);
    long logEvents(in ConnectivityMetricsEvent[] events);

    /**
     * @param reference of the last event previously returned. The function will return
     *                  events following it.
     *                  If 0 then all events will be returned.
     *                  After the function call it will contain reference of the last event.
     */
    ConnectivityMetricsEvent[] getEvents(inout ConnectivityMetricsEvent.Reference reference);

    boolean subscribe(in IConnectivityMetricsLoggerSubscriber subscriber);
    void unsubscribe(in IConnectivityMetricsLoggerSubscriber subscriber);
    boolean register(in PendingIntent newEventsIntent);
    void unregister(in PendingIntent newEventsIntent);
}
Loading