Merge "Add Connectivity Metrics Logger service" into mm-wireless-dev
This commit is contained in:
@@ -189,6 +189,8 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/hardware/usb/IUsbManager.aidl \
|
||||
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 \
|
||||
|
||||
@@ -18207,6 +18207,17 @@ package android.net {
|
||||
method public abstract void onNetworkActive();
|
||||
}
|
||||
|
||||
public class ConnectivityMetricsEvent implements android.os.Parcelable {
|
||||
ctor public ConnectivityMetricsEvent(long, int, int, android.os.Parcelable);
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent> CREATOR;
|
||||
field public final int componentTag;
|
||||
field public final android.os.Parcelable data;
|
||||
field public final int eventTag;
|
||||
field public final long timestamp;
|
||||
}
|
||||
|
||||
public class Credentials {
|
||||
ctor public Credentials(int, int, int);
|
||||
method public int getGid();
|
||||
|
||||
@@ -19720,6 +19720,17 @@ package android.net {
|
||||
method public abstract void onNetworkActive();
|
||||
}
|
||||
|
||||
public class ConnectivityMetricsEvent implements android.os.Parcelable {
|
||||
ctor public ConnectivityMetricsEvent(long, int, int, android.os.Parcelable);
|
||||
method public int describeContents();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.net.ConnectivityMetricsEvent> CREATOR;
|
||||
field public final int componentTag;
|
||||
field public final android.os.Parcelable data;
|
||||
field public final int eventTag;
|
||||
field public final long timestamp;
|
||||
}
|
||||
|
||||
public class Credentials {
|
||||
ctor public Credentials(int, int, int);
|
||||
method public int getGid();
|
||||
|
||||
19
core/java/android/net/ConnectivityMetricsEvent.aidl
Normal file
19
core/java/android/net/ConnectivityMetricsEvent.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
parcelable ConnectivityMetricsEvent;
|
||||
82
core/java/android/net/ConnectivityMetricsEvent.java
Normal file
82
core/java/android/net/ConnectivityMetricsEvent.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@SystemApi
|
||||
public class ConnectivityMetricsEvent implements Parcelable {
|
||||
|
||||
/** The time when this event was collected, as returned by System.currentTimeMillis(). */
|
||||
final public long timestamp;
|
||||
|
||||
/** The subsystem that generated the event. One of the COMPONENT_TAG_xxx constants. */
|
||||
final public int componentTag;
|
||||
|
||||
/** The subsystem-specific event ID. */
|
||||
final public int eventTag;
|
||||
|
||||
/** Opaque event-specific data. */
|
||||
final public Parcelable data;
|
||||
|
||||
public ConnectivityMetricsEvent(long timestamp, int componentTag,
|
||||
int eventTag, Parcelable data) {
|
||||
this.timestamp = timestamp;
|
||||
this.componentTag = componentTag;
|
||||
this.eventTag = eventTag;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface */
|
||||
public static final Parcelable.Creator<ConnectivityMetricsEvent> CREATOR
|
||||
= new Parcelable.Creator<ConnectivityMetricsEvent> (){
|
||||
public ConnectivityMetricsEvent createFromParcel(Parcel source) {
|
||||
final long timestamp = source.readLong();
|
||||
final int componentTag = source.readInt();
|
||||
final int eventTag = source.readInt();
|
||||
final Parcelable data = source.readParcelable(null);
|
||||
return new ConnectivityMetricsEvent(timestamp, componentTag,
|
||||
eventTag, data);
|
||||
}
|
||||
|
||||
public ConnectivityMetricsEvent[] newArray(int size) {
|
||||
return new ConnectivityMetricsEvent[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(timestamp);
|
||||
dest.writeInt(componentTag);
|
||||
dest.writeInt(eventTag);
|
||||
dest.writeParcelable(data, 0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("ConnectivityMetricsEvent(%d, %d, %d)", timestamp,
|
||||
componentTag, eventTag);
|
||||
}
|
||||
}
|
||||
57
core/java/android/net/ConnectivityMetricsLogger.java
Normal file
57
core/java/android/net/ConnectivityMetricsLogger.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
/** {@hide} */
|
||||
public class ConnectivityMetricsLogger {
|
||||
private static String TAG = "ConnectivityMetricsLogger";
|
||||
private static final boolean DBG = true;
|
||||
|
||||
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;
|
||||
|
||||
private IConnectivityMetricsLogger mService;
|
||||
|
||||
public ConnectivityMetricsLogger() {
|
||||
mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService(
|
||||
CONNECTIVITY_METRICS_LOGGER_SERVICE));
|
||||
}
|
||||
|
||||
public void logEvent(long timestamp, int componentTag, int eventTag, Parcelable data) {
|
||||
if (mService == null) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, "logEvent(" + componentTag + "," + eventTag + ") Service not ready");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
mService.logEvent(new ConnectivityMetricsEvent(timestamp, componentTag, eventTag, data));
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error logging event " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
core/java/android/net/IConnectivityMetricsLogger.aidl
Normal file
30
core/java/android/net/IConnectivityMetricsLogger.aidl
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
import android.net.IConnectivityMetricsLoggerSubscriber;
|
||||
|
||||
/** {@hide} */
|
||||
interface IConnectivityMetricsLogger {
|
||||
|
||||
void logEvent(in ConnectivityMetricsEvent event);
|
||||
void logEvents(in ConnectivityMetricsEvent[] events);
|
||||
|
||||
boolean subscribe(in IConnectivityMetricsLoggerSubscriber subscriber);
|
||||
void unsubscribe(in IConnectivityMetricsLoggerSubscriber subscriber);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
|
||||
/** {@hide} */
|
||||
oneway interface IConnectivityMetricsLoggerSubscriber {
|
||||
|
||||
void onEvents(in ConnectivityMetricsEvent[] events);
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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 com.android.server.SystemService;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityMetricsEvent;
|
||||
import android.net.ConnectivityMetricsLogger;
|
||||
import android.net.IConnectivityMetricsLogger;
|
||||
import android.net.IConnectivityMetricsLoggerSubscriber;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** {@hide} */
|
||||
public class MetricsLoggerService extends SystemService {
|
||||
private static String TAG = "ConnectivityMetricsLoggerService";
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = false;
|
||||
|
||||
public MetricsLoggerService(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
||||
Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
|
||||
publishBinderService(ConnectivityMetricsLogger.CONNECTIVITY_METRICS_LOGGER_SERVICE,
|
||||
mBinder);
|
||||
}
|
||||
}
|
||||
|
||||
private final int MAX_NUMBER_OF_EVENTS = 100;
|
||||
private final int MAX_TIME_OFFSET = 15*60*1000; // 15 minutes
|
||||
private final List<ConnectivityMetricsEvent> mEvents = new ArrayList<>();
|
||||
private long mLastSentEventTimeMillis = System.currentTimeMillis();
|
||||
|
||||
private final void enforceConnectivityInternalPermission() {
|
||||
getContext().enforceCallingPermission(
|
||||
android.Manifest.permission.CONNECTIVITY_INTERNAL,
|
||||
"MetricsLoggerService");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the IConnectivityMetricsLogger interface.
|
||||
*/
|
||||
private final IConnectivityMetricsLogger.Stub mBinder = new IConnectivityMetricsLogger.Stub() {
|
||||
|
||||
private final ArrayMap<IConnectivityMetricsLoggerSubscriber,
|
||||
IBinder.DeathRecipient> mSubscribers = new ArrayMap<>();
|
||||
|
||||
|
||||
private ConnectivityMetricsEvent[] prepareEventsToSendIfReady() {
|
||||
ConnectivityMetricsEvent[] eventsToSend = null;
|
||||
final long currentTimeMillis = System.currentTimeMillis();
|
||||
final long timeOffset = currentTimeMillis - mLastSentEventTimeMillis;
|
||||
if (timeOffset >= MAX_TIME_OFFSET
|
||||
|| timeOffset < 0 // system time has changed
|
||||
|| mEvents.size() >= MAX_NUMBER_OF_EVENTS) {
|
||||
// batch events
|
||||
mLastSentEventTimeMillis = currentTimeMillis;
|
||||
eventsToSend = new ConnectivityMetricsEvent[mEvents.size()];
|
||||
mEvents.toArray(eventsToSend);
|
||||
mEvents.clear();
|
||||
}
|
||||
return eventsToSend;
|
||||
}
|
||||
|
||||
private void maybeSendEventsToSubscribers(ConnectivityMetricsEvent[] eventsToSend) {
|
||||
if (eventsToSend == null || eventsToSend.length == 0) return;
|
||||
synchronized (mSubscribers) {
|
||||
for (IConnectivityMetricsLoggerSubscriber s : mSubscribers.keySet()) {
|
||||
try {
|
||||
s.onEvents(eventsToSend);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "RemoteException " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void logEvent(ConnectivityMetricsEvent event) {
|
||||
ConnectivityMetricsEvent[] events = new ConnectivityMetricsEvent[]{event};
|
||||
logEvents(events);
|
||||
}
|
||||
|
||||
public void logEvents(ConnectivityMetricsEvent[] events) {
|
||||
enforceConnectivityInternalPermission();
|
||||
ConnectivityMetricsEvent[] eventsToSend;
|
||||
|
||||
if (VDBG) {
|
||||
for (ConnectivityMetricsEvent e : events) {
|
||||
Log.v(TAG, "writeEvent(" + e.toString() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mEvents) {
|
||||
for (ConnectivityMetricsEvent e : events) {
|
||||
mEvents.add(e);
|
||||
}
|
||||
|
||||
eventsToSend = prepareEventsToSendIfReady();
|
||||
}
|
||||
|
||||
maybeSendEventsToSubscribers(eventsToSend);
|
||||
}
|
||||
|
||||
public boolean subscribe(IConnectivityMetricsLoggerSubscriber subscriber) {
|
||||
enforceConnectivityInternalPermission();
|
||||
if (VDBG) Log.v(TAG, "subscribe");
|
||||
|
||||
synchronized (mSubscribers) {
|
||||
if (mSubscribers.containsKey(subscriber)) {
|
||||
Log.e(TAG, "subscriber is already subscribed");
|
||||
return false;
|
||||
}
|
||||
final IConnectivityMetricsLoggerSubscriber s = subscriber;
|
||||
IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
if (VDBG) Log.v(TAG, "subscriber died");
|
||||
synchronized (mSubscribers) {
|
||||
mSubscribers.remove(s);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
subscriber.asBinder().linkToDeath(dr, 0);
|
||||
mSubscribers.put(subscriber, dr);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "subscribe failed: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void unsubscribe(IConnectivityMetricsLoggerSubscriber subscriber) {
|
||||
enforceConnectivityInternalPermission();
|
||||
if (VDBG) Log.v(TAG, "unsubscribe");
|
||||
synchronized (mSubscribers) {
|
||||
IBinder.DeathRecipient dr = mSubscribers.remove(subscriber);
|
||||
if (dr == null) {
|
||||
Log.e(TAG, "subscriber is not subscribed");
|
||||
return;
|
||||
}
|
||||
subscriber.asBinder().unlinkToDeath(dr, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -56,6 +56,7 @@ import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.audio.AudioService;
|
||||
import com.android.server.camera.CameraService;
|
||||
import com.android.server.clipboard.ClipboardService;
|
||||
import com.android.server.connectivity.MetricsLoggerService;
|
||||
import com.android.server.content.ContentService;
|
||||
import com.android.server.devicepolicy.DevicePolicyManagerService;
|
||||
import com.android.server.display.DisplayManagerService;
|
||||
@@ -552,6 +553,10 @@ public final class SystemServer {
|
||||
} else {
|
||||
mSystemServiceManager.startService(BluetoothService.class);
|
||||
}
|
||||
|
||||
traceBeginAndSlog("ConnectivityMetricsLoggerService");
|
||||
mSystemServiceManager.startService(MetricsLoggerService.class);
|
||||
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.e("System", "******************************************");
|
||||
Slog.e("System", "************ Failure starting core service", e);
|
||||
|
||||
Reference in New Issue
Block a user