19e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt/* 29e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * Copyright (C) 2007 The Android Open Source Project 39e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * 49e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 59e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * you may not use this file except in compliance with the License. 69e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * You may obtain a copy of the License at 79e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * 89e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 99e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * 109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * Unless required by applicable law or agreed to in writing, software 119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * See the License for the specific language governing permissions and 149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt * limitations under the License. 159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt */ 169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltpackage com.android.server; 189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.app.AlarmManager; 209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.app.Notification; 219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.app.NotificationManager; 229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.app.PendingIntent; 239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.BroadcastReceiver; 2481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwaltimport android.content.ContentResolver; 259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.Context; 269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.Intent; 279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.IntentFilter; 289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.pm.PackageManager; 299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.content.res.Resources; 3081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwaltimport android.database.ContentObserver; 31fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwaltimport android.net.INetworkManagementEventObserver; 329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.net.IThrottleManager; 339a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.net.NetworkStats; 349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.net.ThrottleManager; 359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.Binder; 36b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport android.os.Environment; 379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.Handler; 389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.HandlerThread; 399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.IBinder; 409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.INetworkManagementService; 419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.Looper; 429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.Message; 439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.RemoteException; 449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.ServiceManager; 459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.SystemClock; 469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.os.SystemProperties; 479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.provider.Settings; 48e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwaltimport android.telephony.TelephonyManager; 49fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwaltimport android.text.TextUtils; 50b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport android.util.NtpTrustedTime; 519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.util.Slog; 52b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport android.util.TrustedTime; 535f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt 54104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport com.android.internal.R; 55104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport com.android.internal.telephony.TelephonyProperties; 56104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey 57b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.BufferedWriter; 58b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.File; 599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.io.FileDescriptor; 60b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.FileInputStream; 61b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.FileWriter; 62b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.IOException; 639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.io.PrintWriter; 649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.Calendar; 659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.GregorianCalendar; 669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.Random; 67b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport java.util.concurrent.atomic.AtomicInteger; 68b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkeyimport java.util.concurrent.atomic.AtomicLong; 699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt// TODO - add comments - reference the ThrottleManager for public API 719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltpublic class ThrottleService extends IThrottleManager.Stub { 729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String TESTING_ENABLED_PROPERTY = "persist.throttle.testing"; 749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String TAG = "ThrottleService"; 76bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt private static final boolean DBG = true; 77bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt private static final boolean VDBG = false; 789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Handler mHandler; 799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private HandlerThread mThread; 809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Context mContext; 829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 83fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt private static final int INITIAL_POLL_DELAY_SEC = 90; 849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1; 857171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private static final int TESTING_RESET_PERIOD_SEC = 60 * 10; 86d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private static final long TESTING_THRESHOLD = 1 * 1024 * 1024; 879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 88b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private static final long MAX_NTP_CACHE_AGE = 24 * 60 * 60 * 1000; 89b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 90b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private long mMaxNtpCacheAge = MAX_NTP_CACHE_AGE; 91b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 92d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private int mPolicyPollPeriodSec; 9339e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt private AtomicLong mPolicyThreshold; 9439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt private AtomicInteger mPolicyThrottleValue; 959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private int mPolicyResetDay; // 1-28 96d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private int mPolicyNotificationsAllowedMask; 979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private long mLastRead; // read byte count from last poll 999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private long mLastWrite; // write byte count from last poll 1009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String ACTION_POLL = "com.android.server.ThrottleManager.action.POLL"; 1029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static int POLL_REQUEST = 0; 1039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private PendingIntent mPendingPollIntent; 1049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String ACTION_RESET = "com.android.server.ThorottleManager.action.RESET"; 1059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static int RESET_REQUEST = 1; 1069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private PendingIntent mPendingResetIntent; 1079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private INetworkManagementService mNMService; 1099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private AlarmManager mAlarmManager; 1109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private NotificationManager mNotificationManager; 1119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private DataRecorder mRecorder; 1139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 114d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private String mIface; 1159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int NOTIFICATION_WARNING = 2; 1179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Notification mThrottlingNotification; 1199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private boolean mWarningNotificationSent = false; 1209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 121fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private InterfaceObserver mInterfaceObserver; 12281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private SettingsObserver mSettingsObserver; 12381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 12439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt private AtomicInteger mThrottleIndex; // 0 for none, 1 for first throttle val, 2 for next, etc 12581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static final int THROTTLE_INDEX_UNINITIALIZED = -1; 12681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static final int THROTTLE_INDEX_UNTHROTTLED = 0; 12781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 128b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private Intent mPollStickyBroadcast; 129b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 130b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private TrustedTime mTime; 131b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 132b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey private static INetworkManagementService getNetworkManagementService() { 133b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey final IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 134b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey return INetworkManagementService.Stub.asInterface(b); 135b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 1367171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 1379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public ThrottleService(Context context) { 138104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey this(context, getNetworkManagementService(), NtpTrustedTime.getInstance(context), 139b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey context.getResources().getString(R.string.config_datause_iface)); 140b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 141b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 142b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey public ThrottleService(Context context, INetworkManagementService nmService, TrustedTime time, 143b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey String iface) { 1445a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "Starting ThrottleService"); 1459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext = context; 1469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 14724488bd0946f2342fcc725ce55c1347c0698b1e9Robert Greenwalt mPolicyThreshold = new AtomicLong(); 14824488bd0946f2342fcc725ce55c1347c0698b1e9Robert Greenwalt mPolicyThrottleValue = new AtomicInteger(); 14924488bd0946f2342fcc725ce55c1347c0698b1e9Robert Greenwalt mThrottleIndex = new AtomicInteger(); 15024488bd0946f2342fcc725ce55c1347c0698b1e9Robert Greenwalt 151b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mIface = iface; 1529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 1539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent pollIntent = new Intent(ACTION_POLL, null); 1549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); 1559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent resetIntent = new Intent(ACTION_RESET, null); 1569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPendingResetIntent = PendingIntent.getBroadcast(mContext, RESET_REQUEST, resetIntent, 0); 1579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 158b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mNMService = nmService; 159b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mTime = time; 1609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mNotificationManager = (NotificationManager)mContext.getSystemService( 1629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Context.NOTIFICATION_SERVICE); 1639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 1649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 165fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private static class InterfaceObserver extends INetworkManagementEventObserver.Stub { 166fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private int mMsg; 167fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private Handler mHandler; 168fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private String mIface; 169fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 170fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt InterfaceObserver(Handler handler, int msg, String iface) { 171fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt super(); 172fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler = handler; 173fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mMsg = msg; 174fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mIface = iface; 175fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 176fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 177f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen public void interfaceStatusChanged(String iface, boolean up) { 178f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen if (up) { 179fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (TextUtils.equals(iface, mIface)) { 180fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 181fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 182fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 183fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 184fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 185f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen public void interfaceLinkStateChanged(String iface, boolean up) { 186f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen } 187f59c7d0f2ac8d489b6d8118543a57ea4a603eacfMike J. Chen 188fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt public void interfaceAdded(String iface) { 189fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // TODO - an interface added in the UP state should also trigger a StatusChanged 190fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // notification.. 191fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (TextUtils.equals(iface, mIface)) { 192fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 193fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 194fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 195fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 196fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt public void interfaceRemoved(String iface) {} 19712b933d0d9252decaae9fee2456bb1e1cd94c085JP Abgrall public void limitReached(String limitName, String iface) {} 198fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 199fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 200fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 20181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static class SettingsObserver extends ContentObserver { 20281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private int mMsg; 20381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private Handler mHandler; 20481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt SettingsObserver(Handler handler, int msg) { 20581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt super(handler); 20681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mHandler = handler; 20781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mMsg = msg; 20881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 20981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 210b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey void register(Context context) { 21181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt ContentResolver resolver = context.getContentResolver(); 21281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 21381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_POLLING_SEC), false, this); 21481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 215d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_THRESHOLD_BYTES), false, this); 21681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 217d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_VALUE_KBITSPS), false, this); 21881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 21981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY), false, this); 22081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 22181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_NOTIFICATION_TYPE), false, this); 22281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 223d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_HELP_URI), false, this); 224d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 225d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC), false, this); 22681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 22781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 228b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey void unregister(Context context) { 229b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 230b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey resolver.unregisterContentObserver(this); 231b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 232b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 23381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt @Override 23481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt public void onChange(boolean selfChange) { 23581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 23681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 23781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 23881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 2399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void enforceAccessPermission() { 2409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.enforceCallingOrSelfPermission( 2419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, 2429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt "ThrottleService"); 2439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 24505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt private long ntpToWallTime(long ntpTime) { 246b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // get time quickly without worrying about trusted state 247b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey long bestNow = mTime.hasCache() ? mTime.currentTimeMillis() 248b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey : System.currentTimeMillis(); 24905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt long localNow = System.currentTimeMillis(); 25005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt return localNow + (ntpTime - bestNow); 25105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 25205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 253cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2547171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // return time in the local, system wall time, correcting for the use of ntp 25505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 25639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public long getResetTime(String iface) { 2579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 2587171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long resetTime = 0; 259cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (mRecorder != null) { 26039e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt resetTime = mRecorder.getPeriodEnd(); 261d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 26239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt resetTime = ntpToWallTime(resetTime); 2637171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return resetTime; 2649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 265cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff 266cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 26705d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // return time in the local, system wall time, correcting for the use of ntp 26839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public long getPeriodStartTime(String iface) { 2697171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long startTime = 0; 27039e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt enforceAccessPermission(); 271cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (mRecorder != null) { 27239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt startTime = mRecorder.getPeriodStart(); 273d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 27439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt startTime = ntpToWallTime(startTime); 2757171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return startTime; 2769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt //TODO - a better name? getCliffByteCountThreshold? 278cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 27939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public long getCliffThreshold(String iface, int cliff) { 2809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 281cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (cliff == 1) { 28239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt return mPolicyThreshold.get(); 2839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - a better name? getThrottleRate? 287cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 28839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public int getCliffLevel(String iface, int cliff) { 2899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 290cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (cliff == 1) { 29139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt return mPolicyThrottleValue.get(); 2929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 296c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff public String getHelpUri() { 297c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff enforceAccessPermission(); 298c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff return Settings.Secure.getString(mContext.getContentResolver(), 299c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff Settings.Secure.THROTTLE_HELP_URI); 300c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff } 301c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff 302cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 30339e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public long getByteCount(String iface, int dir, int period, int ago) { 3049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 30539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if ((period == ThrottleManager.PERIOD_CYCLE) && (mRecorder != null)) { 3069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (dir == ThrottleManager.DIRECTION_TX) return mRecorder.getPeriodTx(ago); 3079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (dir == ThrottleManager.DIRECTION_RX) return mRecorder.getPeriodRx(ago); 3089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 3109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - a better name - getCurrentThrottleRate? 313cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 31439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt public int getThrottle(String iface) { 3159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 31639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (mThrottleIndex.get() == 1) { 31739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt return mPolicyThrottleValue.get(); 3189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 3209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt void systemReady() { 3235a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "systemReady"); 3249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.registerReceiver( 3259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt new BroadcastReceiver() { 3269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 3279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void onReceive(Context context, Intent intent) { 328b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey dispatchPoll(); 3299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt }, new IntentFilter(ACTION_POLL)); 3319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.registerReceiver( 3339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt new BroadcastReceiver() { 3349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 3359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void onReceive(Context context, Intent intent) { 336b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey dispatchReset(); 3379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt }, new IntentFilter(ACTION_RESET)); 3399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 340c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt // use a new thread as we don't want to stall the system for file writes 341c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mThread = new HandlerThread(TAG); 342c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mThread.start(); 343c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mHandler = new MyHandler(mThread.getLooper()); 344c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mHandler.obtainMessage(EVENT_REBOOT_RECOVERY).sendToTarget(); 345c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt 346c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mInterfaceObserver = new InterfaceObserver(mHandler, EVENT_IFACE_UP, mIface); 347c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt try { 348c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mNMService.registerObserver(mInterfaceObserver); 349c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt } catch (RemoteException e) { 350c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt Slog.e(TAG, "Could not register InterfaceObserver " + e); 351c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt } 352c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt 353c76c15e255b01412e5cda33b606d7672713b6665Robert Greenwalt mSettingsObserver = new SettingsObserver(mHandler, EVENT_POLICY_CHANGED); 354b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mSettingsObserver.register(mContext); 355b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 356b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 357b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey void shutdown() { 358b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // TODO: eventually connect with ShutdownThread to persist stats during 359b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // graceful shutdown. 360b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 361b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mThread != null) { 362b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mThread.quit(); 363b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 364b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 365b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mSettingsObserver != null) { 366b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mSettingsObserver.unregister(mContext); 367b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 368b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 369b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mPollStickyBroadcast != null) { 370b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mContext.removeStickyBroadcast(mPollStickyBroadcast); 371b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 3729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 374b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey void dispatchPoll() { 375b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mHandler.obtainMessage(EVENT_POLL_ALARM).sendToTarget(); 376b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 377b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey 378b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey void dispatchReset() { 379b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget(); 380b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 3819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_REBOOT_RECOVERY = 0; 3839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_POLICY_CHANGED = 1; 3849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_POLL_ALARM = 2; 3859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_RESET_ALARM = 3; 386fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private static final int EVENT_IFACE_UP = 4; 3879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private class MyHandler extends Handler { 3889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public MyHandler(Looper l) { 3899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt super(l); 3909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 3939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void handleMessage(Message msg) { 3949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt switch (msg.what) { 3959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_REBOOT_RECOVERY: 3969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onRebootRecovery(); 3979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 3989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_POLICY_CHANGED: 3999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onPolicyChanged(); 4009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 4019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_POLL_ALARM: 4029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onPollAlarm(); 4039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 4049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_RESET_ALARM: 4059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onResetAlarm(); 406fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt break; 407fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt case EVENT_IFACE_UP: 408fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt onIfaceUp(); 4099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onRebootRecovery() { 4135a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "onRebootRecovery"); 4149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check for sim change TODO 4159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // reregister for notification of policy change 4169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 41739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mThrottleIndex.set(THROTTLE_INDEX_UNINITIALIZED); 4189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mRecorder = new DataRecorder(mContext, ThrottleService.this); 4209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // get policy 4229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler.obtainMessage(EVENT_POLICY_CHANGED).sendToTarget(); 423fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt 424fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // if we poll now we won't have network connectivity or even imsi access 425fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // queue up a poll to happen in a little while - after ntp and imsi are avail 426fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // TODO - make this callback based (ie, listen for notificaitons) 427fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_POLL_ALARM), 428fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt INITIAL_POLL_DELAY_SEC * 1000); 4299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check for new policy info (threshold limit/value/etc) 4329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onPolicyChanged() { 4339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt boolean testing = SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true"); 4349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 435d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int pollingPeriod = mContext.getResources().getInteger( 4367171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_polling_period_sec); 4379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyPollPeriodSec = Settings.Secure.getInt(mContext.getContentResolver(), 4389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_POLLING_SEC, pollingPeriod); 4399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove testing stuff? 441d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt long defaultThreshold = mContext.getResources().getInteger( 4427171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_threshold_bytes); 443d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int defaultValue = mContext.getResources().getInteger( 4447171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_throttle_kbitsps); 44539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt long threshold = Settings.Secure.getLong(mContext.getContentResolver(), 44639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt Settings.Secure.THROTTLE_THRESHOLD_BYTES, defaultThreshold); 44739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt int value = Settings.Secure.getInt(mContext.getContentResolver(), 44839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt Settings.Secure.THROTTLE_VALUE_KBITSPS, defaultValue); 44939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt 45039e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThreshold.set(threshold); 45139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThrottleValue.set(value); 45239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (testing) { 45339e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyPollPeriodSec = TESTING_POLLING_PERIOD_SEC; 45439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThreshold.set(TESTING_THRESHOLD); 4559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 456d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt 4579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyResetDay = Settings.Secure.getInt(mContext.getContentResolver(), 4589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY, -1); 4599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mPolicyResetDay == -1 || 4609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ((mPolicyResetDay < 1) || (mPolicyResetDay > 28))) { 4619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Random g = new Random(); 4629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyResetDay = 1 + g.nextInt(28); // 1-28 4639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.putInt(mContext.getContentResolver(), 4649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY, mPolicyResetDay); 4659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 46639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (mIface == null) { 46739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThreshold.set(0); 4689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 470d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int defaultNotificationType = mContext.getResources().getInteger( 4717171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_notification_type); 4729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyNotificationsAllowedMask = Settings.Secure.getInt(mContext.getContentResolver(), 473d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_NOTIFICATION_TYPE, defaultNotificationType); 4749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 475b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey final int maxNtpCacheAgeSec = Settings.Secure.getInt(mContext.getContentResolver(), 476b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC, 477b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey (int) (MAX_NTP_CACHE_AGE / 1000)); 478b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mMaxNtpCacheAge = maxNtpCacheAgeSec * 1000; 479d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt 480687f2a07bf76863fba4a7dc1c92ae69cca049039Robert Greenwalt if (VDBG || (mPolicyThreshold.get() != 0)) { 4815a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt Slog.d(TAG, "onPolicyChanged testing=" + testing +", period=" + 482687f2a07bf76863fba4a7dc1c92ae69cca049039Robert Greenwalt mPolicyPollPeriodSec + ", threshold=" + mPolicyThreshold.get() + 483687f2a07bf76863fba4a7dc1c92ae69cca049039Robert Greenwalt ", value=" + mPolicyThrottleValue.get() + ", resetDay=" + mPolicyResetDay + 484b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey ", noteType=" + mPolicyNotificationsAllowedMask + ", mMaxNtpCacheAge=" + 485b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mMaxNtpCacheAge); 4865a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt } 4879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4885bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt // force updates 48939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mThrottleIndex.set(THROTTLE_INDEX_UNINITIALIZED); 4905bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt 49181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt onResetAlarm(); 4929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 493b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt onPollAlarm(); 494b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 49581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.POLICY_CHANGED_ACTION); 49681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mContext.sendBroadcast(broadcast); 4979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onPollAlarm() { 5009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long now = SystemClock.elapsedRealtime(); 501b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey long next = now + mPolicyPollPeriodSec * 1000; 5027171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 503b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // when trusted cache outdated, try refreshing 504b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mTime.getCacheAge() > mMaxNtpCacheAge) { 505b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mTime.forceRefresh()) { 506b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (VDBG) Slog.d(TAG, "updated trusted time, reseting alarm"); 507b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey dispatchReset(); 508b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 509b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 5107171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 5119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long incRead = 0; 5129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long incWrite = 0; 5139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 514e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey final NetworkStats stats = mNMService.getNetworkStatsSummaryDev(); 515b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int index = stats.findIndex(mIface, NetworkStats.UID_ALL, 516b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE); 5179a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 5189a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey if (index != -1) { 519d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats.Entry entry = stats.getValues(index, null); 520d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey incRead = entry.rxBytes - mLastRead; 521d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey incWrite = entry.txBytes - mLastWrite; 5229a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } else { 5239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey // missing iface, assume stats are 0 5249a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey Slog.w(TAG, "unable to find stats for iface " + mIface); 5259a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5269a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 5278c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt // handle iface resets - on some device the 3g iface comes and goes and gets 5288c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt // totals reset to 0. Deal with it 5298c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt if ((incRead < 0) || (incWrite < 0)) { 5308c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt incRead += mLastRead; 5318c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt incWrite += mLastWrite; 5328c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt mLastRead = 0; 5338c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt mLastWrite = 0; 5348c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt } 535558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey } catch (IllegalStateException e) { 536558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey Slog.e(TAG, "problem during onPollAlarm: " + e); 5379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (RemoteException e) { 538558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey Slog.e(TAG, "problem during onPollAlarm: " + e); 5399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 540558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey 5415f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt // don't count this data if we're roaming. 5425f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt boolean roaming = "true".equals( 5435f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING)); 5445f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt if (!roaming) { 5455f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt mRecorder.addData(incRead, incWrite); 5465f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt } 5479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long periodRx = mRecorder.getPeriodRx(0); 5499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long periodTx = mRecorder.getPeriodTx(0); 5509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long total = periodRx + periodTx; 551687f2a07bf76863fba4a7dc1c92ae69cca049039Robert Greenwalt if (VDBG || (mPolicyThreshold.get() != 0)) { 552bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt Slog.d(TAG, "onPollAlarm - roaming =" + roaming + 5535f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt ", read =" + incRead + ", written =" + incWrite + ", new total =" + total); 5549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mLastRead += incRead; 5569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mLastWrite += incWrite; 5579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt checkThrottleAndPostNotification(total); 5599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION); 5619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx); 5629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx); 56305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, getPeriodStartTime(mIface)); 56405d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, getResetTime(mIface)); 5659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 566b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mPollStickyBroadcast = broadcast; 5679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 568d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mAlarmManager.cancel(mPendingPollIntent); 5695a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); 5709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 572fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private void onIfaceUp() { 573fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // if we were throttled before, be sure and set it again - the iface went down 574fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // (and may have disappeared all together) and these settings were lost 57539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (mThrottleIndex.get() == 1) { 576fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt try { 577fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mNMService.setInterfaceThrottle(mIface, -1, -1); 578fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mNMService.setInterfaceThrottle(mIface, 57939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThrottleValue.get(), mPolicyThrottleValue.get()); 580fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } catch (Exception e) { 581fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt Slog.e(TAG, "error setting Throttle: " + e); 582fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 583fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 584fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 585fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 5869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void checkThrottleAndPostNotification(long currentTotal) { 587d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt // is throttling enabled? 58839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt long threshold = mPolicyThreshold.get(); 58939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (threshold == 0) { 590cce83379ef5ddd122ffe6fcce431cb86d059a74bRobert Greenwalt clearThrottleAndNotification(); 5919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return; 5927171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 5937171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 5947171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // have we spoken with an ntp server yet? 5957171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // this is controversial, but we'd rather err towards not throttling 596b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (!mTime.hasCache()) { 597b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey Slog.w(TAG, "missing trusted time, skipping throttle check"); 5987171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return; 5997171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 6009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check if we need to throttle 60239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (currentTotal > threshold) { 60339e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (mThrottleIndex.get() != 1) { 60439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mThrottleIndex.set(1); 60539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (DBG) Slog.d(TAG, "Threshold " + threshold + " exceeded!"); 6069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 607d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mNMService.setInterfaceThrottle(mIface, 60839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThrottleValue.get(), mPolicyThrottleValue.get()); 6099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (Exception e) { 6109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.e(TAG, "error setting Throttle: " + e); 6119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6137171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 6149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6157171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt postNotification(R.string.throttled_notification_title, 6167171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.string.throttled_notification_message, 6177171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.drawable.stat_sys_throttled, 618c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt Notification.FLAG_ONGOING_EVENT); 6199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION); 62139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, 62239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThrottleValue.get()); 6239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 6249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } // else already up! 6269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } else { 6275bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt clearThrottleAndNotification(); 6289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if ((mPolicyNotificationsAllowedMask & NOTIFICATION_WARNING) != 0) { 6299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check if we should warn about throttle 630e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // pretend we only have 1/2 the time remaining that we actually do 631e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // if our burn rate in the period so far would have us exceed the limit 632e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // in that 1/2 window, warn the user. 633e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // this gets more generous in the early to middle period and converges back 634e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // to the limit as we move toward the period end. 635e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt 636e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // adding another factor - it must be greater than the total cap/4 637e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // else we may get false alarms very early in the period.. in the first 638e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // tenth of a percent of the period if we used more than a tenth of a percent 639e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // of the cap we'd get a warning and that's not desired. 640e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long start = mRecorder.getPeriodStart(); 641e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long end = mRecorder.getPeriodEnd(); 642e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long periodLength = end - start; 643e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long now = System.currentTimeMillis(); 644e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long timeUsed = now - start; 64539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt long warningThreshold = 2*threshold*timeUsed/(timeUsed+periodLength); 64639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if ((currentTotal > warningThreshold) && (currentTotal > threshold/4)) { 647e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt if (mWarningNotificationSent == false) { 648e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt mWarningNotificationSent = true; 6497171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 6507171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt postNotification(R.string.throttle_warning_notification_title, 6517171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.string.throttle_warning_notification_message, 6527171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.drawable.stat_sys_throttled, 653e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt 0); 654e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt } 6559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } else { 656e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt if (mWarningNotificationSent == true) { 6577171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 658e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt mWarningNotificationSent =false; 659e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt } 6609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 665c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt private void postNotification(int titleInt, int messageInt, int icon, int flags) { 6669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent intent = new Intent(); 6679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - fix up intent 6682a7b730378a0c9d7c3dfbc47e9862169a149d347Robert Greenwalt intent.setClassName("com.android.phone", "com.android.phone.DataUsage"); 6699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 6709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 6729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Resources r = Resources.getSystem(); 6749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt CharSequence title = r.getText(titleInt); 6759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt CharSequence message = r.getText(messageInt); 6769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mThrottlingNotification == null) { 6779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification = new Notification(); 6789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.when = 0; 6799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - fixup icon 6809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.icon = icon; 6819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.defaults &= ~Notification.DEFAULT_SOUND; 6829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 683c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt mThrottlingNotification.flags = flags; 6849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.tickerText = title; 6859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.setLatestEventInfo(mContext, title, message, pi); 6869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mNotificationManager.notify(mThrottlingNotification.icon, mThrottlingNotification); 6889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 69139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt private void clearThrottleAndNotification() { 69239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (mThrottleIndex.get() != THROTTLE_INDEX_UNTHROTTLED) { 69339e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mThrottleIndex.set(THROTTLE_INDEX_UNTHROTTLED); 6949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 695d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mNMService.setInterfaceThrottle(mIface, -1, -1); 6969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (Exception e) { 6979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.e(TAG, "error clearing Throttle: " + e); 6989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION); 7009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1); 7019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 7025bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 7035bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt mWarningNotificationSent = false; 7049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7077171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private Calendar calculatePeriodEnd(long now) { 7089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar end = GregorianCalendar.getInstance(); 7097171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt end.setTimeInMillis(now); 7109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int day = end.get(Calendar.DAY_OF_MONTH); 7119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.DAY_OF_MONTH, mPolicyResetDay); 7129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.HOUR_OF_DAY, 0); 7139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.MINUTE, 0); 7148c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt end.set(Calendar.SECOND, 0); 7158c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt end.set(Calendar.MILLISECOND, 0); 7169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (day >= mPolicyResetDay) { 7179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int month = end.get(Calendar.MONTH); 7189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (month == Calendar.DECEMBER) { 7199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.YEAR, end.get(Calendar.YEAR) + 1); 7209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt month = Calendar.JANUARY - 1; 7219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.MONTH, month + 1); 7239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove! 7269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) { 7279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end = GregorianCalendar.getInstance(); 7287171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt end.setTimeInMillis(now); 7299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.add(Calendar.SECOND, TESTING_RESET_PERIOD_SEC); 7309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return end; 7329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Calendar calculatePeriodStart(Calendar end) { 7349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar start = (Calendar)end.clone(); 7359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int month = end.get(Calendar.MONTH); 7369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (end.get(Calendar.MONTH) == Calendar.JANUARY) { 7379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt month = Calendar.DECEMBER + 1; 7389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.set(Calendar.YEAR, start.get(Calendar.YEAR) - 1); 7399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.set(Calendar.MONTH, month - 1); 7419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove!! 7439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) { 7449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start = (Calendar)end.clone(); 7459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.add(Calendar.SECOND, -TESTING_RESET_PERIOD_SEC); 7469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return start; 7489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onResetAlarm() { 751687f2a07bf76863fba4a7dc1c92ae69cca049039Robert Greenwalt if (VDBG || (mPolicyThreshold.get() != 0)) { 7529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.d(TAG, "onResetAlarm - last period had " + mRecorder.getPeriodRx(0) + 7539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt " bytes read and " + mRecorder.getPeriodTx(0) + " written"); 7549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 756b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // when trusted cache outdated, try refreshing 757b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mTime.getCacheAge() > mMaxNtpCacheAge) { 758b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey mTime.forceRefresh(); 759b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 7609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 761b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // as long as we have a trusted time cache, we always reset alarms, 762b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey // even if the refresh above failed. 763b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (mTime.hasCache()) { 764b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey final long now = mTime.currentTimeMillis(); 7657171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Calendar end = calculatePeriodEnd(now); 7667171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Calendar start = calculatePeriodStart(end); 7679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7687171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (mRecorder.setNextPeriod(start, end)) { 76905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt onPollAlarm(); 7707171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7717171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 7727171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mAlarmManager.cancel(mPendingResetIntent); 7737171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long offset = end.getTimeInMillis() - now; 7747171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // use Elapsed realtime so clock changes don't fool us. 7755a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, 7767171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt SystemClock.elapsedRealtime() + offset, 7777171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mPendingResetIntent); 7787171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } else { 779b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (VDBG) Slog.d(TAG, "no trusted time, not resetting period"); 7807171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7817171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7827171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7837171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 7849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // records bytecount data for a given time and accumulates it into larger time windows 7859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // for logging and other purposes 7869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 7879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // since time can be changed (user or network action) we will have to track the time of the 7889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // last recording and deal with it. 7899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static class DataRecorder { 7909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long[] mPeriodRxData; 7919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long[] mPeriodTxData; 7929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int mCurrentPeriod; 7939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int mPeriodCount; 7949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar mPeriodStart; 7969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar mPeriodEnd; 7979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ThrottleService mParent; 7999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Context mContext; 800e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String mImsi = null; 801e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 802e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt TelephonyManager mTelephonyManager; 8039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt DataRecorder(Context context, ThrottleService parent) { 8059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext = context; 8069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mParent = parent; 8079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 808e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt mTelephonyManager = (TelephonyManager)mContext.getSystemService( 809e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt Context.TELEPHONY_SERVICE); 810e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 8119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodCount = 6; 8139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData = new long[mPeriodCount]; 8149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData = new long[mPeriodCount]; 8159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart = Calendar.getInstance(); 8179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd = Calendar.getInstance(); 8189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt retrieve(); 8209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8237171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt boolean setNextPeriod(Calendar start, Calendar end) { 824e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // TODO - how would we deal with a dual-IMSI device? 825e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkForSubscriberId(); 8267171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt boolean startNewPeriod = true; 827bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt 82827fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt if (start.equals(mPeriodStart) && end.equals(mPeriodEnd)) { 82927fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt // same endpoints - keep collecting 8305a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) { 83127fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "same period (" + start.getTimeInMillis() + "," + 83227fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() +") - ammending data"); 8339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 83427fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt startNewPeriod = false; 83527fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } else { 8365a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) { 83727fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt if(start.equals(mPeriodEnd) || start.after(mPeriodEnd)) { 83827fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "next period (" + start.getTimeInMillis() + "," + 83927fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() + ") - old end was " + 84027fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodEnd.getTimeInMillis() + ", following"); 84127fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } else { 84227fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "new period (" + start.getTimeInMillis() + "," + 84327fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() + ") replacing old (" + 84427fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodStart.getTimeInMillis() + "," + 84527fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodEnd.getTimeInMillis() + ")"); 84627fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } 8479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ++mCurrentPeriod; 8509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mCurrentPeriod >= mPeriodCount) mCurrentPeriod = 0; 8519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[mCurrentPeriod] = 0; 8529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[mCurrentPeriod] = 0; 8539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt setPeriodStart(start); 8569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt setPeriodEnd(end); 8579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt record(); 8587171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return startNewPeriod; 8599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public long getPeriodEnd() { 8629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodEnd.getTimeInMillis(); 8649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void setPeriodEnd(Calendar end) { 8689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd = end; 8709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public long getPeriodStart() { 8749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodStart.getTimeInMillis(); 8769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void setPeriodStart(Calendar start) { 8809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart = start; 8829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public int getPeriodCount() { 8869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodCount; 8889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void zeroData(int field) { 8929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt for(int period = 0; period<mPeriodCount; period++) { 8949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[period] = 0; 8959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[period] = 0; 8969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mCurrentPeriod = 0; 8989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 9009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 9019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 9029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // if time moves backward accumulate all read/write that's lost into the now 9039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // otherwise time moved forward. 9049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt void addData(long bytesRead, long bytesWritten) { 905e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkForSubscriberId(); 9067171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 9079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 9089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[mCurrentPeriod] += bytesRead; 9099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[mCurrentPeriod] += bytesWritten; 9109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 9119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt record(); 9129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 9139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 914b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private File getDataFile() { 915b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File dataDir = Environment.getDataDirectory(); 916b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File throttleDir = new File(dataDir, "system/throttle"); 917b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt throttleDir.mkdirs(); 918e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String mImsi = mTelephonyManager.getSubscriberId(); 919e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File dataFile; 920e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi == null) { 921e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile = useMRUFile(throttleDir); 922bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (VDBG) Slog.v(TAG, "imsi not available yet, using " + dataFile); 923e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } else { 924e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String imsiHash = Integer.toString(mImsi.hashCode()); 925e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile = new File(throttleDir, imsiHash); 926e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 927e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // touch the file so it's not LRU 928e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile.setLastModified(System.currentTimeMillis()); 929e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkAndDeleteLRUDataFile(throttleDir); 930b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return dataFile; 931b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 932b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 933e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // TODO - get broadcast (TelephonyIntents.ACTION_SIM_STATE_CHANGED) instead of polling 934e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private void checkForSubscriberId() { 935e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi != null) return; 936e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 937e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt mImsi = mTelephonyManager.getSubscriberId(); 938e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi == null) return; 939e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 9405a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.d(TAG, "finally have imsi - retreiving data"); 941e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt retrieve(); 942e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 943e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 944e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private final static int MAX_SIMS_SUPPORTED = 3; 945e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 946e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private void checkAndDeleteLRUDataFile(File dir) { 947e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File[] files = dir.listFiles(); 948e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 949b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (files == null || files.length <= MAX_SIMS_SUPPORTED) return; 950bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (DBG) Slog.d(TAG, "Too many data files"); 951e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt do { 952e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File oldest = null; 953e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt for (File f : files) { 954e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if ((oldest == null) || (oldest.lastModified() > f.lastModified())) { 955e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt oldest = f; 956e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 957e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 958e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (oldest == null) return; 959bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (DBG) Slog.d(TAG, " deleting " + oldest); 960e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt oldest.delete(); 961e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt files = dir.listFiles(); 962e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } while (files.length > MAX_SIMS_SUPPORTED); 963e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 964e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 965e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private File useMRUFile(File dir) { 966e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File newest = null; 967e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File[] files = dir.listFiles(); 968e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 969b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if (files != null) { 970b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey for (File f : files) { 971b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey if ((newest == null) || (newest.lastModified() < f.lastModified())) { 972b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey newest = f; 973b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey } 974e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 975e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 976e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (newest == null) { 977e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt newest = new File(dir, "temp"); 978e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 979e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt return newest; 980e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 981e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 982e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 983b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private static final int DATA_FILE_VERSION = 1; 9849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 985b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private void record() { 986b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt // 1 int version 9879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 1 int mPeriodCount 9889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13*6 long[PERIOD_COUNT] mPeriodRxData 9899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13*6 long[PERIOD_COUNT] mPeriodTxData 9909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 1 int mCurrentPeriod 9919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13 long periodStartMS 9929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13 long periodEndMS 993b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt // 200 chars max 9949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt StringBuilder builder = new StringBuilder(); 995b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt builder.append(DATA_FILE_VERSION); 996b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt builder.append(":"); 9979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodCount); 9989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 999b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 10009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodRxData[i]); 10019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 10029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 1003b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 10049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodTxData[i]); 10059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 10069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mCurrentPeriod); 10089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 10099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodStart.getTimeInMillis()); 10109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 10119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodEnd.getTimeInMillis()); 10129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1013b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt BufferedWriter out = null; 1014b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 10157171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt out = new BufferedWriter(new FileWriter(getDataFile()), 256); 1016b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt out.write(builder.toString()); 1017b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (IOException e) { 1018b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "Error writing data file"); 1019b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 1020b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } finally { 1021b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (out != null) { 1022b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 1023b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt out.close(); 1024b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (Exception e) {} 1025b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1026b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 10279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void retrieve() { 103005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // clean out any old data first. If we fail to read we don't want old stuff 103105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt zeroData(0); 103205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 1033b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File f = getDataFile(); 1034b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt byte[] buffer; 1035b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt FileInputStream s = null; 1036b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 1037b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt buffer = new byte[(int)f.length()]; 1038b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s = new FileInputStream(f); 1039b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s.read(buffer); 1040b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (IOException e) { 1041b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "Error reading data file"); 1042b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 1043b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } finally { 1044b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (s != null) { 1045b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 1046b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s.close(); 1047b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (Exception e) {} 1048b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1049b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1050b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt String data = new String(buffer); 10517171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (data == null || data.length() == 0) { 10527171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (DBG) Slog.d(TAG, "data file empty"); 10537171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return; 10547171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 105539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt String[] parsed = data.split(":"); 105639e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt int parsedUsed = 0; 105739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt if (parsed.length < 6) { 105839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt Slog.e(TAG, "reading data file with insufficient length - ignoring"); 105939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt return; 106039e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt } 1061b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 10629e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt int periodCount; 10639e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt long[] periodRxData; 10649e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt long[] periodTxData; 10659e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt int currentPeriod; 10669e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt Calendar periodStart; 10679e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt Calendar periodEnd; 10689e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt try { 10699e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt if (Integer.parseInt(parsed[parsedUsed++]) != DATA_FILE_VERSION) { 10709e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt Slog.e(TAG, "reading data file with bad version - ignoring"); 10719e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt return; 10729e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt } 10739e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt 10749e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodCount = Integer.parseInt(parsed[parsedUsed++]); 10759e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt if (parsed.length != 5 + (2 * periodCount)) { 10769e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt Slog.e(TAG, "reading data file with bad length (" + parsed.length + 10779e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt " != " + (5 + (2 * periodCount)) + ") - ignoring"); 10789e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt return; 10799e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt } 10809e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodRxData = new long[periodCount]; 10819e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt for (int i = 0; i < periodCount; i++) { 10829e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodRxData[i] = Long.parseLong(parsed[parsedUsed++]); 10839e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt } 10849e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodTxData = new long[periodCount]; 10859e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt for (int i = 0; i < periodCount; i++) { 10869e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodTxData[i] = Long.parseLong(parsed[parsedUsed++]); 10879e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt } 10889e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt 10899e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt currentPeriod = Integer.parseInt(parsed[parsedUsed++]); 10909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10919e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodStart = new GregorianCalendar(); 10929e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodStart.setTimeInMillis(Long.parseLong(parsed[parsedUsed++])); 10939e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodEnd = new GregorianCalendar(); 10949e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt periodEnd.setTimeInMillis(Long.parseLong(parsed[parsedUsed++])); 10959e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt } catch (Exception e) { 10969e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt Slog.e(TAG, "Error parsing data file - ignoring"); 109739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt return; 109839e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt } 109939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt synchronized (mParent) { 110039e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPeriodCount = periodCount; 110139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPeriodRxData = periodRxData; 110239e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPeriodTxData = periodTxData; 11039e3983fbde2f86c116ffbc40491ff7aedd7d2fc7Robert Greenwalt mCurrentPeriod = currentPeriod; 110439e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPeriodStart = periodStart; 110539e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPeriodEnd = periodEnd; 11069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 11099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long getPeriodRx(int which) { 11109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 11119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which > mPeriodCount) return 0; 11129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt which = mCurrentPeriod - which; 11139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which < 0) which += mPeriodCount; 11149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodRxData[which]; 11159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long getPeriodTx(int which) { 11189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 11199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which > mPeriodCount) return 0; 11209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt which = mCurrentPeriod - which; 11219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which < 0) which += mPeriodCount; 11229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodTxData[which]; 11239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 11279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 11289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mContext.checkCallingOrSelfPermission( 11309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt android.Manifest.permission.DUMP) 11319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt != PackageManager.PERMISSION_GRANTED) { 11329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Permission Denial: can't dump ThrottleService " + 11339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 11349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Binder.getCallingUid()); 11359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return; 11369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println(); 11389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 113939e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt pw.println("The threshold is " + mPolicyThreshold.get() + 11409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ", after which you experince throttling to " + 114139e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt mPolicyThrottleValue.get() + "kbps"); 11429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Current period is " + 11439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt (mRecorder.getPeriodEnd() - mRecorder.getPeriodStart())/1000 + " seconds long " + 11447171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt "and ends in " + (getResetTime(mIface) - System.currentTimeMillis()) / 1000 + 11459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt " seconds."); 11469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Polling every " + mPolicyPollPeriodSec + " seconds"); 114739e163f45afa1c86be91717c2ed216b66255a65fRobert Greenwalt pw.println("Current Throttle Index is " + mThrottleIndex.get()); 1148b7342acebcb7e5dc7da0cda77fbddf50e7dfdd7cJeff Sharkey pw.println("mMaxNtpCacheAge=" + mMaxNtpCacheAge); 11498c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt 11509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt for (int i = 0; i < mRecorder.getPeriodCount(); i++) { 11519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println(" Period[" + i + "] - read:" + mRecorder.getPeriodRx(i) + ", written:" + 11529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mRecorder.getPeriodTx(i)); 11539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt} 1156