1b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock/* 24cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk * Copyright (C) 2015 The Android Open Source Project 3b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * 4b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * you may not use this file except in compliance with the License. 6b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * You may obtain a copy of the License at 7b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * 8b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * 10b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * Unless required by applicable law or agreed to in writing, software 11b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * See the License for the specific language governing permissions and 14b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock * limitations under the License. 15b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock */ 16b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 174cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkpackage com.android.settingslib.net; 18b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 19b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.content.Context; 20b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.net.ConnectivityManager; 21b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.net.INetworkStatsService; 22b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.net.INetworkStatsSession; 235e9049a362016c9f00823346d619303674f9df0eJohn Spurlockimport android.net.NetworkPolicy; 245e9049a362016c9f00823346d619303674f9df0eJohn Spurlockimport android.net.NetworkPolicyManager; 25b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.net.NetworkStatsHistory; 26b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.net.NetworkTemplate; 27b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.os.RemoteException; 28b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.os.ServiceManager; 29b574627ebc383d35cf8212ee241b191b26518a0dJason Monkimport android.telephony.SubscriptionManager; 30b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.telephony.TelephonyManager; 31b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.text.format.DateUtils; 32d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlockimport android.text.format.Time; 33b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport android.util.Log; 34b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 357aeb3f54408a7bd0c1ca3020bca32900b2091b1dAndrew Sappersteinimport com.android.internal.R; 3670196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang 37b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlockimport java.util.Date; 38d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlockimport java.util.Locale; 39b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 404cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.net.ConnectivityManager.TYPE_MOBILE; 414cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.net.NetworkStatsHistory.FIELD_RX_BYTES; 424cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.net.NetworkStatsHistory.FIELD_TX_BYTES; 434cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.telephony.TelephonyManager.SIM_STATE_READY; 444cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.text.format.DateUtils.FORMAT_ABBREV_MONTH; 454cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monkimport static android.text.format.DateUtils.FORMAT_SHOW_DATE; 4670196d84a640ed4781e3d79a4dfe2015126238ffFan Zhangimport static android.net.TrafficStats.MB_IN_BYTES; 474cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk 48f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monkpublic class DataUsageController { 4970196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang 50f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk private static final String TAG = "DataUsageController"; 51d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 52b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES; 53d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50); 54d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter( 55d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock PERIOD_BUILDER, Locale.getDefault()); 56b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 57b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private final Context mContext; 58b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private final TelephonyManager mTelephonyManager; 59b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private final ConnectivityManager mConnectivityManager; 60b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private final INetworkStatsService mStatsService; 615e9049a362016c9f00823346d619303674f9df0eJohn Spurlock private final NetworkPolicyManager mPolicyManager; 62b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 63b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private INetworkStatsSession mSession; 64b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private Callback mCallback; 654cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk private NetworkNameProvider mNetworkController; 66b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 67f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk public DataUsageController(Context context) { 68b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mContext = context; 69b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mTelephonyManager = TelephonyManager.from(context); 70b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mConnectivityManager = ConnectivityManager.from(context); 71b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mStatsService = INetworkStatsService.Stub.asInterface( 72b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 735e9049a362016c9f00823346d619303674f9df0eJohn Spurlock mPolicyManager = NetworkPolicyManager.from(mContext); 74cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock } 755e9049a362016c9f00823346d619303674f9df0eJohn Spurlock 764cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public void setNetworkController(NetworkNameProvider networkController) { 77d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk mNetworkController = networkController; 78d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk } 79d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk 8070196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang /** 8170196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang * Returns the default warning level in bytes. 8270196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang */ 8370196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang public long getDefaultWarningLevel() { 8470196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang return MB_IN_BYTES 8570196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang * mContext.getResources().getInteger(R.integer.default_data_warning_level_mb); 8670196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang } 8770196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang 88cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock private INetworkStatsSession getSession() { 89cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock if (mSession == null) { 90cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock try { 91cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock mSession = mStatsService.openSession(); 92cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock } catch (RemoteException e) { 93cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock Log.w(TAG, "Failed to open stats session", e); 94cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock } catch (RuntimeException e) { 95cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock Log.w(TAG, "Failed to open stats session", e); 96cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock } 97b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 98cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock return mSession; 99b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 100b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 101b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public void setCallback(Callback callback) { 102b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mCallback = callback; 103b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 104b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 105b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private DataUsageInfo warn(String msg) { 106b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock Log.w(TAG, "Failed to get data usage, " + msg); 107b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return null; 108b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 109b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 110d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock private static Time addMonth(Time t, int months) { 111d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock final Time rt = new Time(t); 112d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock rt.set(t.monthDay, t.month + months, t.year); 113d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock rt.normalize(false); 114d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock return rt; 115d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } 116d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock 117b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public DataUsageInfo getDataUsageInfo() { 118b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final String subscriberId = getActiveSubscriberId(mContext); 119b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock if (subscriberId == null) { 120b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return warn("no subscriber id"); 121b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 122f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId); 123f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk template = NetworkTemplate.normalize(template, mTelephonyManager.getMergedSubscriberIds()); 124f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk 125f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk return getDataUsageInfo(template); 126f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk } 127f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk 128f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk public DataUsageInfo getWifiDataUsageInfo() { 129f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard(); 130f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk return getDataUsageInfo(template); 131f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk } 132f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk 133f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk public DataUsageInfo getDataUsageInfo(NetworkTemplate template) { 134cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock final INetworkStatsSession session = getSession(); 135cfa39d269bf404f6121889ebc431fbf20a79eb2aJohn Spurlock if (session == null) { 136b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return warn("no stats session"); 137b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 1385e9049a362016c9f00823346d619303674f9df0eJohn Spurlock final NetworkPolicy policy = findNetworkPolicy(template); 139b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock try { 140f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS); 141b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final long now = System.currentTimeMillis(); 142d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock final long start, end; 143d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock if (policy != null && policy.cycleDay > 0) { 144d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock // period = determined from cycleDay 145d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock if (DEBUG) Log.d(TAG, "Cycle day=" + policy.cycleDay + " tz=" 146d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock + policy.cycleTimezone); 147d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock final Time nowTime = new Time(policy.cycleTimezone); 148d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock nowTime.setToNow(); 149d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock final Time policyTime = new Time(nowTime); 150d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock policyTime.set(policy.cycleDay, policyTime.month, policyTime.year); 151d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock policyTime.normalize(false); 152d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock if (nowTime.after(policyTime)) { 153d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock start = policyTime.toMillis(false); 154d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock end = addMonth(policyTime, 1).toMillis(false); 155d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } else { 156d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock start = addMonth(policyTime, -1).toMillis(false); 157d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock end = policyTime.toMillis(false); 158d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } 159d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } else { 160d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock // period = last 4 wks 161d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock end = now; 162d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock start = now - DateUtils.WEEK_IN_MILLIS * 4; 163d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } 164b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final long callStart = System.currentTimeMillis(); 165b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null); 166b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final long callEnd = System.currentTimeMillis(); 167b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock if (DEBUG) Log.d(TAG, String.format("history call from %s to %s now=%s took %sms: %s", 168b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock new Date(start), new Date(end), new Date(now), callEnd - callStart, 169b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock historyEntryToString(entry))); 170b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock if (entry == null) { 171b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return warn("no entry data"); 172b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 173b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final long totalBytes = entry.rxBytes + entry.txBytes; 174b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final DataUsageInfo usage = new DataUsageInfo(); 175f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk usage.startDate = start; 176b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock usage.usageLevel = totalBytes; 177d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock usage.period = formatDateRange(start, end); 1785e9049a362016c9f00823346d619303674f9df0eJohn Spurlock if (policy != null) { 1795e9049a362016c9f00823346d619303674f9df0eJohn Spurlock usage.limitLevel = policy.limitBytes > 0 ? policy.limitBytes : 0; 1805e9049a362016c9f00823346d619303674f9df0eJohn Spurlock usage.warningLevel = policy.warningBytes > 0 ? policy.warningBytes : 0; 181d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } else { 18270196d84a640ed4781e3d79a4dfe2015126238ffFan Zhang usage.warningLevel = getDefaultWarningLevel(); 1835e9049a362016c9f00823346d619303674f9df0eJohn Spurlock } 1844cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk if (usage != null && mNetworkController != null) { 1855504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak usage.carrier = mNetworkController.getMobileDataNetworkName(); 186d2263cd9db36d5f74a124c5ffaf8594ef702408fJason Monk } 187b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return usage; 188b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } catch (RemoteException e) { 189b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return warn("remote call failed"); 190b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 191b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 192b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 1935e9049a362016c9f00823346d619303674f9df0eJohn Spurlock private NetworkPolicy findNetworkPolicy(NetworkTemplate template) { 1945e9049a362016c9f00823346d619303674f9df0eJohn Spurlock if (mPolicyManager == null || template == null) return null; 1955e9049a362016c9f00823346d619303674f9df0eJohn Spurlock final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies(); 1965e9049a362016c9f00823346d619303674f9df0eJohn Spurlock if (policies == null) return null; 1975e9049a362016c9f00823346d619303674f9df0eJohn Spurlock final int N = policies.length; 1985e9049a362016c9f00823346d619303674f9df0eJohn Spurlock for (int i = 0; i < N; i++) { 1995e9049a362016c9f00823346d619303674f9df0eJohn Spurlock final NetworkPolicy policy = policies[i]; 2005e9049a362016c9f00823346d619303674f9df0eJohn Spurlock if (policy != null && template.equals(policy.template)) { 2015e9049a362016c9f00823346d619303674f9df0eJohn Spurlock return policy; 2025e9049a362016c9f00823346d619303674f9df0eJohn Spurlock } 2035e9049a362016c9f00823346d619303674f9df0eJohn Spurlock } 2045e9049a362016c9f00823346d619303674f9df0eJohn Spurlock return null; 2055e9049a362016c9f00823346d619303674f9df0eJohn Spurlock } 2065e9049a362016c9f00823346d619303674f9df0eJohn Spurlock 207b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private static String historyEntryToString(NetworkStatsHistory.Entry entry) { 208b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return entry == null ? null : new StringBuilder("Entry[") 209b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append("bucketDuration=").append(entry.bucketDuration) 210b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",bucketStart=").append(entry.bucketStart) 211b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",activeTime=").append(entry.activeTime) 212b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",rxBytes=").append(entry.rxBytes) 213b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",rxPackets=").append(entry.rxPackets) 214b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",txBytes=").append(entry.txBytes) 215b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",txPackets=").append(entry.txPackets) 216b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(",operations=").append(entry.operations) 217b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock .append(']').toString(); 218b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 219b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 220b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public void setMobileDataEnabled(boolean enabled) { 22136ffb0494dd1045c164b7479b68165e206f8c759Wink Saville Log.d(TAG, "setMobileDataEnabled: enabled=" + enabled); 222b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mTelephonyManager.setDataEnabled(enabled); 223b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock if (mCallback != null) { 224b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock mCallback.onMobileDataEnabled(enabled); 225b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 226b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 227b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 228b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public boolean isMobileDataSupported() { 229b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock // require both supported network and ready SIM 230b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return mConnectivityManager.isNetworkSupported(TYPE_MOBILE) 231b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock && mTelephonyManager.getSimState() == SIM_STATE_READY; 232b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 233b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 234b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public boolean isMobileDataEnabled() { 235b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return mTelephonyManager.getDataEnabled(); 236b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 237b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 238b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock private static String getActiveSubscriberId(Context context) { 239b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock final TelephonyManager tele = TelephonyManager.from(context); 240b574627ebc383d35cf8212ee241b191b26518a0dJason Monk final String actualSubscriberId = tele.getSubscriberId( 2417ea3e8bf8954343d7b243b6a23bcb8339921f3c8Shishir Agrawal SubscriptionManager.getDefaultDataSubscriptionId()); 242b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock return actualSubscriberId; 243b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 244b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock 245d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock private String formatDateRange(long start, long end) { 246d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock final int flags = FORMAT_SHOW_DATE | FORMAT_ABBREV_MONTH; 247d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock synchronized (PERIOD_BUILDER) { 248d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock PERIOD_BUILDER.setLength(0); 249d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock return DateUtils.formatDateRange(mContext, PERIOD_FORMATTER, start, end, flags, null) 250d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock .toString(); 251d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } 252d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock } 253d11a19b8ea08035c14052ee42cbc529e62cc4c70John Spurlock 2544cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public interface NetworkNameProvider { 2554cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk String getMobileDataNetworkName(); 2564cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk } 2574cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk 2584cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public static class DataUsageInfo { 2594cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public String carrier; 2604cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public String period; 261f668d7cceb3c6cc9143fcf92230681bddd7ccf21Jason Monk public long startDate; 2624cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public long limitLevel; 2634cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public long warningLevel; 2644cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk public long usageLevel; 2654cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk } 2664cf95aef839701a43c9bde292f5e2d8ca3213509Jason Monk 267b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock public interface Callback { 268b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock void onMobileDataEnabled(boolean enabled); 269b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock } 270b98f747c714ff8252471ca0a3295c2cb9ccb4f3aJohn Spurlock} 271