102b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak/* 202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * Copyright (C) 2016 The Android Open Source Project 302b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * 402b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * Licensed under the Apache License, Version 2.0 (the "License"); 502b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * you may not use this file except in compliance with the License. 602b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * You may obtain a copy of the License at 702b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * 802b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * http://www.apache.org/licenses/LICENSE-2.0 902b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * 1002b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * Unless required by applicable law or agreed to in writing, software 1102b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * distributed under the License is distributed on an "AS IS" BASIS, 1202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1302b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * See the License for the specific language governing permissions and 1402b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak * limitations under the License. 1502b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak */ 1602b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakpackage android.net; 1702b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 18f6f24c03f39016ee927e8bdbcff75a53841829c8Pavel Zhamaitsiakimport android.annotation.SystemApi; 19c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiakimport android.app.PendingIntent; 20d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiakimport android.os.Bundle; 2102b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakimport android.os.Parcelable; 2202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakimport android.os.RemoteException; 2302b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakimport android.os.ServiceManager; 2402b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakimport android.util.Log; 2502b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 2602b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak/** {@hide} */ 27f6f24c03f39016ee927e8bdbcff75a53841829c8Pavel Zhamaitsiak@SystemApi 2802b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiakpublic class ConnectivityMetricsLogger { 2902b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak private static String TAG = "ConnectivityMetricsLogger"; 3002b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak private static final boolean DBG = true; 3102b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 3202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak public static final String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger"; 3302b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 3402b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak // Component Tags 35d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int COMPONENT_TAG_CONNECTIVITY = 0; 36d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int COMPONENT_TAG_BLUETOOTH = 1; 37d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int COMPONENT_TAG_WIFI = 2; 38d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int COMPONENT_TAG_TELECOM = 3; 39d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int COMPONENT_TAG_TELEPHONY = 4; 40d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 41d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int NUMBER_OF_COMPONENTS = 5; 42d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 43d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak // Event Tag 44d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final int TAG_SKIPPED_EVENTS = -1; 45d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 46d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak public static final String DATA_KEY_EVENTS_COUNT = "count"; 4702b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 4802b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak private IConnectivityMetricsLogger mService; 4902b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 50d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak private long mServiceUnblockedTimestampMillis = 0; 51d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak private int mNumSkippedEvents = 0; 52d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 5302b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak public ConnectivityMetricsLogger() { 5402b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService( 5502b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak CONNECTIVITY_METRICS_LOGGER_SERVICE)); 5602b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak } 5702b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak 5802b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak public void logEvent(long timestamp, int componentTag, int eventTag, Parcelable data) { 5902b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak if (mService == null) { 6002b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak if (DBG) { 6102b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak Log.d(TAG, "logEvent(" + componentTag + "," + eventTag + ") Service not ready"); 6202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak } 63d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak return; 64d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 65d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 66d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (mServiceUnblockedTimestampMillis > 0) { 67d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (System.currentTimeMillis() < mServiceUnblockedTimestampMillis) { 68d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak // Service is throttling events. 69d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak // Don't send new events because they will be dropped. 70d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak mNumSkippedEvents++; 71d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak return; 72d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 73d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 74d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 75d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak ConnectivityMetricsEvent skippedEventsEvent = null; 76d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (mNumSkippedEvents > 0) { 77d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak // Log number of skipped events 78d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak Bundle b = new Bundle(); 79d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak b.putInt(DATA_KEY_EVENTS_COUNT, mNumSkippedEvents); 80d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak skippedEventsEvent = new ConnectivityMetricsEvent(mServiceUnblockedTimestampMillis, 81d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak componentTag, TAG_SKIPPED_EVENTS, b); 82d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 83d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak mServiceUnblockedTimestampMillis = 0; 84d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 85d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 86d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak ConnectivityMetricsEvent event = new ConnectivityMetricsEvent(timestamp, componentTag, 87d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak eventTag, data); 88d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 89d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak try { 90d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak long result; 91d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (skippedEventsEvent == null) { 92d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak result = mService.logEvent(event); 93d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } else { 94d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak result = mService.logEvents(new ConnectivityMetricsEvent[] 95d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak {skippedEventsEvent, event}); 96d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 97d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak 98d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (result == 0) { 99d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak mNumSkippedEvents = 0; 100d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } else { 101d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak mNumSkippedEvents++; 102d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak if (result > 0) { // events are throttled 103d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak mServiceUnblockedTimestampMillis = result; 104d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } 10502b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak } 106d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak } catch (RemoteException e) { 107d1cb256b3efd2c00f1c44541b5589c2ea17b3cb8Pavel Zhamaitsiak Log.e(TAG, "Error logging event " + e.getMessage()); 10802b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak } 10902b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak } 110c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak 111c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak /** 112c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * Retrieve events 113c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * 114c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * @param reference of the last event previously returned. The function will return 115c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * events following it. 116c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * If 0 then all events will be returned. 117c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * After the function call it will contain reference of the 118c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * last returned event. 119c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * @return events 120c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak */ 121c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) { 122c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak try { 123c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return mService.getEvents(reference); 124c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } catch (RemoteException ex) { 125c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak Log.e(TAG, "IConnectivityMetricsLogger.getEvents: " + ex); 126c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return null; 127c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 128c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 129c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak 130c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak /** 131c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak * Register PendingIntent which will be sent when new events are ready to be retrieved. 132c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak */ 133c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak public boolean register(PendingIntent newEventsIntent) { 134c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak try { 135c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return mService.register(newEventsIntent); 136c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } catch (RemoteException ex) { 137c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak Log.e(TAG, "IConnectivityMetricsLogger.register: " + ex); 138c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return false; 139c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 140c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 141c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak 142c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak public boolean unregister(PendingIntent newEventsIntent) { 143c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak try { 144c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak mService.unregister(newEventsIntent); 145c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } catch (RemoteException ex) { 146c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak Log.e(TAG, "IConnectivityMetricsLogger.unregister: " + ex); 147c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return false; 148c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 149c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak 150c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak return true; 151c2c39e28f3ae7f993821dda55b69605989967f60Pavel Zhamaitsiak } 15202b3e6bfc5bbd5f1a8ce1ce68976e59142073b6fPavel Zhamaitsiak} 153