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; 337171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwaltimport android.net.SntpClient; 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; 509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport android.util.Slog; 519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 527171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwaltimport com.android.internal.R; 535f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwaltimport com.android.internal.telephony.TelephonyProperties; 545f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt 55b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.BufferedWriter; 56b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.File; 579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.io.FileDescriptor; 58b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.FileInputStream; 59b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.FileWriter; 60b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwaltimport java.io.IOException; 619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.io.PrintWriter; 629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.Calendar; 639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.GregorianCalendar; 647171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwaltimport java.util.Properties; 659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltimport java.util.Random; 669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt// TODO - add comments - reference the ThrottleManager for public API 689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwaltpublic class ThrottleService extends IThrottleManager.Stub { 699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String TESTING_ENABLED_PROPERTY = "persist.throttle.testing"; 719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String TAG = "ThrottleService"; 73bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt private static final boolean DBG = true; 74bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt private static final boolean VDBG = false; 759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Handler mHandler; 769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private HandlerThread mThread; 779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Context mContext; 799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 80fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt private static final int INITIAL_POLL_DELAY_SEC = 90; 819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1; 827171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private static final int TESTING_RESET_PERIOD_SEC = 60 * 10; 83d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private static final long TESTING_THRESHOLD = 1 * 1024 * 1024; 849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 85d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private int mPolicyPollPeriodSec; 869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private long mPolicyThreshold; 879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private int mPolicyThrottleValue; 889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private int mPolicyResetDay; // 1-28 89d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private int mPolicyNotificationsAllowedMask; 909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private long mLastRead; // read byte count from last poll 929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private long mLastWrite; // write byte count from last poll 939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String ACTION_POLL = "com.android.server.ThrottleManager.action.POLL"; 959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static int POLL_REQUEST = 0; 969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private PendingIntent mPendingPollIntent; 979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final String ACTION_RESET = "com.android.server.ThorottleManager.action.RESET"; 989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static int RESET_REQUEST = 1; 999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private PendingIntent mPendingResetIntent; 1009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private INetworkManagementService mNMService; 1029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private AlarmManager mAlarmManager; 1039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private NotificationManager mNotificationManager; 1049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private DataRecorder mRecorder; 1069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 107d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt private String mIface; 1089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int NOTIFICATION_WARNING = 2; 1109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Notification mThrottlingNotification; 1129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private boolean mWarningNotificationSent = false; 1139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 114fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private InterfaceObserver mInterfaceObserver; 11581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private SettingsObserver mSettingsObserver; 11681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 11781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private int mThrottleIndex; // 0 for none, 1 for first throttle val, 2 for next, etc 11881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static final int THROTTLE_INDEX_UNINITIALIZED = -1; 11981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static final int THROTTLE_INDEX_UNTHROTTLED = 0; 12081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 1217171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1227171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private String mNtpServer; 1237171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private boolean mNtpActive; 1247171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 1259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public ThrottleService(Context context) { 1265a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "Starting ThrottleService"); 1279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext = context; 1289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1297171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNtpActive = false; 1307171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 131fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mIface = mContext.getResources().getString(R.string.config_datause_iface); 1329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 1339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent pollIntent = new Intent(ACTION_POLL, null); 1349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); 1359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent resetIntent = new Intent(ACTION_RESET, null); 1369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPendingResetIntent = PendingIntent.getBroadcast(mContext, RESET_REQUEST, resetIntent, 0); 1379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); 1399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mNMService = INetworkManagementService.Stub.asInterface(b); 1409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 1419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mNotificationManager = (NotificationManager)mContext.getSystemService( 1429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Context.NOTIFICATION_SERVICE); 1439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 1449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 145fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private static class InterfaceObserver extends INetworkManagementEventObserver.Stub { 146fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private int mMsg; 147fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private Handler mHandler; 148fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private String mIface; 149fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 150fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt InterfaceObserver(Handler handler, int msg, String iface) { 151fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt super(); 152fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler = handler; 153fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mMsg = msg; 154fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mIface = iface; 155fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 156fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 157fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt public void interfaceLinkStatusChanged(String iface, boolean link) { 158fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (link) { 159fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (TextUtils.equals(iface, mIface)) { 160fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 161fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 162fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 163fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 164fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 165fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt public void interfaceAdded(String iface) { 166fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // TODO - an interface added in the UP state should also trigger a StatusChanged 167fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // notification.. 168fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (TextUtils.equals(iface, mIface)) { 169fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 170fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 171fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 172fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 173fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt public void interfaceRemoved(String iface) {} 174fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 175fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 176fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 17781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private static class SettingsObserver extends ContentObserver { 17881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private int mMsg; 17981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt private Handler mHandler; 18081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt SettingsObserver(Handler handler, int msg) { 18181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt super(handler); 18281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mHandler = handler; 18381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mMsg = msg; 18481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 18581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 18681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt void observe(Context context) { 18781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt ContentResolver resolver = context.getContentResolver(); 18881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 18981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_POLLING_SEC), false, this); 19081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 191d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_THRESHOLD_BYTES), false, this); 19281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 193d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_VALUE_KBITSPS), false, this); 19481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 19581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY), false, this); 19681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 19781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Settings.Secure.THROTTLE_NOTIFICATION_TYPE), false, this); 19881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 199d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_HELP_URI), false, this); 200d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt resolver.registerContentObserver(Settings.Secure.getUriFor( 201d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC), false, this); 20281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 20381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 20481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt @Override 20581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt public void onChange(boolean selfChange) { 20681aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mHandler.obtainMessage(mMsg).sendToTarget(); 20781aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 20881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt } 20981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 2109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void enforceAccessPermission() { 2119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.enforceCallingOrSelfPermission( 2129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, 2139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt "ThrottleService"); 2149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 21605d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt private long ntpToWallTime(long ntpTime) { 21705d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt long bestNow = getBestTime(); 21805d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt long localNow = System.currentTimeMillis(); 21905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt return localNow + (ntpTime - bestNow); 22005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 22105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 222cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2237171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // return time in the local, system wall time, correcting for the use of ntp 22405d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 2259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized long getResetTime(String iface) { 2269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 2277171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long resetTime = 0; 228cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (mRecorder != null) { 22905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt resetTime = ntpToWallTime(mRecorder.getPeriodEnd()); 230d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 2317171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return resetTime; 2329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 233cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff 234cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 23505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // return time in the local, system wall time, correcting for the use of ntp 2369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized long getPeriodStartTime(String iface) { 2379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 2387171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long startTime = 0; 239cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (mRecorder != null) { 24005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt startTime = ntpToWallTime(mRecorder.getPeriodStart()); 241d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 2427171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return startTime; 2439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt //TODO - a better name? getCliffByteCountThreshold? 245cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized long getCliffThreshold(String iface, int cliff) { 2479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 248cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (cliff == 1) { 2499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPolicyThreshold; 2509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - a better name? getThrottleRate? 254cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized int getCliffLevel(String iface, int cliff) { 2569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 257cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (cliff == 1) { 2589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPolicyThrottleValue; 2599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 263c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff public String getHelpUri() { 264c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff enforceAccessPermission(); 265c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff return Settings.Secure.getString(mContext.getContentResolver(), 266c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff Settings.Secure.THROTTLE_HELP_URI); 267c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff } 268c9b6851af68bdc20c4903b16c344e9f116647219Irfan Sheriff 269cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized long getByteCount(String iface, int dir, int period, int ago) { 2719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 272cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if ((period == ThrottleManager.PERIOD_CYCLE) && 2739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt (mRecorder != null)) { 2749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (dir == ThrottleManager.DIRECTION_TX) return mRecorder.getPeriodTx(ago); 2759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (dir == ThrottleManager.DIRECTION_RX) return mRecorder.getPeriodRx(ago); 2769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 2809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - a better name - getCurrentThrottleRate? 281cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff // TODO - fetch for the iface 2829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public synchronized int getThrottle(String iface) { 2839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt enforceAccessPermission(); 284cf28236b3784e285632e272b99cf1f8fc01f016bIrfan Sheriff if (mThrottleIndex == 1) { 2859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPolicyThrottleValue; 2869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return 0; 2889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 2909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt void systemReady() { 2915a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "systemReady"); 2929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.registerReceiver( 2939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt new BroadcastReceiver() { 2949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 2959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void onReceive(Context context, Intent intent) { 2969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler.obtainMessage(EVENT_POLL_ALARM).sendToTarget(); 2979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 2989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt }, new IntentFilter(ACTION_POLL)); 2999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.registerReceiver( 3019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt new BroadcastReceiver() { 3029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 3039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void onReceive(Context context, Intent intent) { 3049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget(); 3059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt }, new IntentFilter(ACTION_RESET)); 3079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // use a new thread as we don't want to stall the system for file writes 3099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThread = new HandlerThread(TAG); 3109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThread.start(); 3119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler = new MyHandler(mThread.getLooper()); 3129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler.obtainMessage(EVENT_REBOOT_RECOVERY).sendToTarget(); 31381aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt 314fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mInterfaceObserver = new InterfaceObserver(mHandler, EVENT_IFACE_UP, mIface); 315fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt try { 316fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mNMService.registerObserver(mInterfaceObserver); 317fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } catch (RemoteException e) { 318fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt Slog.e(TAG, "Could not register InterfaceObserver " + e); 319fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 320fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 32181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mSettingsObserver = new SettingsObserver(mHandler, EVENT_POLICY_CHANGED); 32281aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mSettingsObserver.observe(mContext); 3237171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 3247171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt FileInputStream stream = null; 3257171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt try { 3267171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Properties properties = new Properties(); 3277171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt File file = new File(PROPERTIES_FILE); 3287171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt stream = new FileInputStream(file); 3297171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt properties.load(stream); 3307171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNtpServer = properties.getProperty("NTP_SERVER", null); 3317171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } catch (IOException e) { 3327171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3337171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } finally { 3347171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (stream != null) { 3357171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt try { 3367171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt stream.close(); 3377171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } catch (Exception e) {} 3387171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 3397171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 3409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_REBOOT_RECOVERY = 0; 3449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_POLICY_CHANGED = 1; 3459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_POLL_ALARM = 2; 3469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static final int EVENT_RESET_ALARM = 3; 347fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private static final int EVENT_IFACE_UP = 4; 3489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private class MyHandler extends Handler { 3499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public MyHandler(Looper l) { 3509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt super(l); 3519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 3549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public void handleMessage(Message msg) { 3559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt switch (msg.what) { 3569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_REBOOT_RECOVERY: 3579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onRebootRecovery(); 3589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 3599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_POLICY_CHANGED: 3609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onPolicyChanged(); 3619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 3629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_POLL_ALARM: 3639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onPollAlarm(); 3649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt break; 3659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt case EVENT_RESET_ALARM: 3669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt onResetAlarm(); 367fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt break; 368fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt case EVENT_IFACE_UP: 369fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt onIfaceUp(); 3709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onRebootRecovery() { 3745a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.v(TAG, "onRebootRecovery"); 3759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check for sim change TODO 3769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // reregister for notification of policy change 3779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 37881aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mThrottleIndex = THROTTLE_INDEX_UNINITIALIZED; 3799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mRecorder = new DataRecorder(mContext, ThrottleService.this); 3819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // get policy 3839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mHandler.obtainMessage(EVENT_POLICY_CHANGED).sendToTarget(); 384fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt 385fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // if we poll now we won't have network connectivity or even imsi access 386fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // queue up a poll to happen in a little while - after ntp and imsi are avail 387fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt // TODO - make this callback based (ie, listen for notificaitons) 388fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_POLL_ALARM), 389fb9896b5cdb149594fa1b36ac77038d90091a957Robert Greenwalt INITIAL_POLL_DELAY_SEC * 1000); 3909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 3919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 3929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check for new policy info (threshold limit/value/etc) 3939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onPolicyChanged() { 3949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt boolean testing = SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true"); 3959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 396d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int pollingPeriod = mContext.getResources().getInteger( 3977171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_polling_period_sec); 3989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyPollPeriodSec = Settings.Secure.getInt(mContext.getContentResolver(), 3999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_POLLING_SEC, pollingPeriod); 4009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove testing stuff? 402d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt long defaultThreshold = mContext.getResources().getInteger( 4037171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_threshold_bytes); 404d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int defaultValue = mContext.getResources().getInteger( 4057171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_throttle_kbitsps); 4069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (ThrottleService.this) { 4079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyThreshold = Settings.Secure.getLong(mContext.getContentResolver(), 408d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_THRESHOLD_BYTES, defaultThreshold); 4099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyThrottleValue = Settings.Secure.getInt(mContext.getContentResolver(), 410d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_VALUE_KBITSPS, defaultValue); 411d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt if (testing) { 412d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mPolicyPollPeriodSec = TESTING_POLLING_PERIOD_SEC; 413d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mPolicyThreshold = TESTING_THRESHOLD; 414d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 4159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 416d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt 4179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyResetDay = Settings.Secure.getInt(mContext.getContentResolver(), 4189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY, -1); 4199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mPolicyResetDay == -1 || 4209e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ((mPolicyResetDay < 1) || (mPolicyResetDay > 28))) { 4219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Random g = new Random(); 4229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyResetDay = 1 + g.nextInt(28); // 1-28 4239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.putInt(mContext.getContentResolver(), 4249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Settings.Secure.THROTTLE_RESET_DAY, mPolicyResetDay); 4259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (ThrottleService.this) { 427d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt if (mIface == null) { 428d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mPolicyThreshold = 0; 429d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt } 4309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 432d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt int defaultNotificationType = mContext.getResources().getInteger( 4337171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.integer.config_datause_notification_type); 4349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyNotificationsAllowedMask = Settings.Secure.getInt(mContext.getContentResolver(), 435d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt Settings.Secure.THROTTLE_NOTIFICATION_TYPE, defaultNotificationType); 4369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 437d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt mMaxNtpCacheAgeSec = Settings.Secure.getInt(mContext.getContentResolver(), 438d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC, MAX_NTP_CACHE_AGE_SEC); 439d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt 4405a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG || (mPolicyThreshold != 0)) { 4415a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt Slog.d(TAG, "onPolicyChanged testing=" + testing +", period=" + 4425a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mPolicyPollPeriodSec + ", threshold=" + mPolicyThreshold + ", value=" + 4435a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mPolicyThrottleValue + ", resetDay=" + mPolicyResetDay + ", noteType=" + 4445a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mPolicyNotificationsAllowedMask + ", maxNtpCacheAge=" + mMaxNtpCacheAgeSec); 4455a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt } 4469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4475bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt // force updates 4485bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt mThrottleIndex = THROTTLE_INDEX_UNINITIALIZED; 4495bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt 45081aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt onResetAlarm(); 4519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 452b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt onPollAlarm(); 453b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 45481aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.POLICY_CHANGED_ACTION); 45581aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mContext.sendBroadcast(broadcast); 4569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onPollAlarm() { 4599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long now = SystemClock.elapsedRealtime(); 4609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long next = now + mPolicyPollPeriodSec*1000; 4617171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 4627171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt checkForAuthoritativeTime(); 4637171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 4649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long incRead = 0; 4659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long incWrite = 0; 4669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 467d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt incRead = mNMService.getInterfaceRxCounter(mIface) - mLastRead; 468d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt incWrite = mNMService.getInterfaceTxCounter(mIface) - mLastWrite; 4698c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt // handle iface resets - on some device the 3g iface comes and goes and gets 4708c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt // totals reset to 0. Deal with it 4718c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt if ((incRead < 0) || (incWrite < 0)) { 4728c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt incRead += mLastRead; 4738c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt incWrite += mLastWrite; 4748c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt mLastRead = 0; 4758c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt mLastWrite = 0; 4768c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt } 4779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (RemoteException e) { 4789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.e(TAG, "got remoteException in onPollAlarm:" + e); 4799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4805f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt // don't count this data if we're roaming. 4815f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt boolean roaming = "true".equals( 4825f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING)); 4835f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt if (!roaming) { 4845f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt mRecorder.addData(incRead, incWrite); 4855f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt } 4869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long periodRx = mRecorder.getPeriodRx(0); 4889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long periodTx = mRecorder.getPeriodTx(0); 4899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long total = periodRx + periodTx; 4905a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG || (mPolicyThreshold != 0)) { 491bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt Slog.d(TAG, "onPollAlarm - roaming =" + roaming + 4925f996899b058f0eb6655d3fe3fd3a5d93256e6c5Robert Greenwalt ", read =" + incRead + ", written =" + incWrite + ", new total =" + total); 4939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 4949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mLastRead += incRead; 4959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mLastWrite += incWrite; 4969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt checkThrottleAndPostNotification(total); 4989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 4999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION); 5009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx); 5019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx); 50205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, getPeriodStartTime(mIface)); 50305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, getResetTime(mIface)); 5049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 5059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 506d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mAlarmManager.cancel(mPendingPollIntent); 5075a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); 5089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 510fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt private void onIfaceUp() { 511fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // if we were throttled before, be sure and set it again - the iface went down 512fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt // (and may have disappeared all together) and these settings were lost 513fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt if (mThrottleIndex == 1) { 514fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt try { 515fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mNMService.setInterfaceThrottle(mIface, -1, -1); 516fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mNMService.setInterfaceThrottle(mIface, 517fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt mPolicyThrottleValue, mPolicyThrottleValue); 518fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } catch (Exception e) { 519fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt Slog.e(TAG, "error setting Throttle: " + e); 520fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 521fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 522fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt } 523fee4683f47b43626af98ed9aade27917d4da2d8aRobert Greenwalt 5249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void checkThrottleAndPostNotification(long currentTotal) { 525d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt // is throttling enabled? 5267171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (mPolicyThreshold == 0) { 527cce83379ef5ddd122ffe6fcce431cb86d059a74bRobert Greenwalt clearThrottleAndNotification(); 5289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return; 5297171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 5307171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 5317171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // have we spoken with an ntp server yet? 5327171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // this is controversial, but we'd rather err towards not throttling 5337171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if ((mNtpServer != null) && !mNtpActive) { 5347171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return; 5357171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 5369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check if we need to throttle 5389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (currentTotal > mPolicyThreshold) { 53981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt if (mThrottleIndex != 1) { 5409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (ThrottleService.this) { 54181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mThrottleIndex = 1; 5429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (DBG) Slog.d(TAG, "Threshold " + mPolicyThreshold + " exceeded!"); 5449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 545d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mNMService.setInterfaceThrottle(mIface, 5469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyThrottleValue, mPolicyThrottleValue); 5479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (Exception e) { 5489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.e(TAG, "error setting Throttle: " + e); 5499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5517171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 5529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5537171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt postNotification(R.string.throttled_notification_title, 5547171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.string.throttled_notification_message, 5557171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.drawable.stat_sys_throttled, 556c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt Notification.FLAG_ONGOING_EVENT); 5579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION); 5599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, mPolicyThrottleValue); 5609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 5619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 5629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } // else already up! 5639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } else { 5645bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt clearThrottleAndNotification(); 5659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if ((mPolicyNotificationsAllowedMask & NOTIFICATION_WARNING) != 0) { 5669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // check if we should warn about throttle 567e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // pretend we only have 1/2 the time remaining that we actually do 568e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // if our burn rate in the period so far would have us exceed the limit 569e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // in that 1/2 window, warn the user. 570e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // this gets more generous in the early to middle period and converges back 571e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // to the limit as we move toward the period end. 572e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt 573e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // adding another factor - it must be greater than the total cap/4 574e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // else we may get false alarms very early in the period.. in the first 575e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // tenth of a percent of the period if we used more than a tenth of a percent 576e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt // of the cap we'd get a warning and that's not desired. 577e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long start = mRecorder.getPeriodStart(); 578e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long end = mRecorder.getPeriodEnd(); 579e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long periodLength = end - start; 580e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long now = System.currentTimeMillis(); 581e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long timeUsed = now - start; 582e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt long warningThreshold = 2*mPolicyThreshold*timeUsed/(timeUsed+periodLength); 583e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt if ((currentTotal > warningThreshold) && (currentTotal > mPolicyThreshold/4)) { 584e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt if (mWarningNotificationSent == false) { 585e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt mWarningNotificationSent = true; 5867171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 5877171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt postNotification(R.string.throttle_warning_notification_title, 5887171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.string.throttle_warning_notification_message, 5897171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt R.drawable.stat_sys_throttled, 590e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt 0); 591e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt } 5929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } else { 593e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt if (mWarningNotificationSent == true) { 5947171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 595e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt mWarningNotificationSent =false; 596e2c0ce03631fc81651b8bde578e993c25e3291e9Robert Greenwalt } 5979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 5999e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 602c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt private void postNotification(int titleInt, int messageInt, int icon, int flags) { 6039e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent intent = new Intent(); 6049e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - fix up intent 6052a7b730378a0c9d7c3dfbc47e9862169a149d347Robert Greenwalt intent.setClassName("com.android.phone", "com.android.phone.DataUsage"); 6069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 6079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); 6099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Resources r = Resources.getSystem(); 6119e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt CharSequence title = r.getText(titleInt); 6129e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt CharSequence message = r.getText(messageInt); 6139e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mThrottlingNotification == null) { 6149e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification = new Notification(); 6159e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.when = 0; 6169e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - fixup icon 6179e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.icon = icon; 6189e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.defaults &= ~Notification.DEFAULT_SOUND; 6199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 620c87dc6dc90d0953c10051dceb470ff05e2fb9300Robert Greenwalt mThrottlingNotification.flags = flags; 6219e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.tickerText = title; 6229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mThrottlingNotification.setLatestEventInfo(mContext, title, message, pi); 6239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mNotificationManager.notify(mThrottlingNotification.icon, mThrottlingNotification); 6259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private synchronized void clearThrottleAndNotification() { 62981aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt if (mThrottleIndex != THROTTLE_INDEX_UNTHROTTLED) { 6309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (ThrottleService.this) { 63181aa0971d7a26ae16ed34fc7da97a55d97fb8e74Robert Greenwalt mThrottleIndex = THROTTLE_INDEX_UNTHROTTLED; 6329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6339e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt try { 634d3bb93f6870581eebbf08b5b7fb0a9c5eaad8b16Robert Greenwalt mNMService.setInterfaceThrottle(mIface, -1, -1); 6359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } catch (Exception e) { 6369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.e(TAG, "error clearing Throttle: " + e); 6379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION); 6399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1); 6409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext.sendStickyBroadcast(broadcast); 6415bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt mNotificationManager.cancel(R.drawable.stat_sys_throttled); 6425bf16d6e8c0afae4e60590ffbdbed1bd6e73ff8bRobert Greenwalt mWarningNotificationSent = false; 6439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6467171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private Calendar calculatePeriodEnd(long now) { 6479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar end = GregorianCalendar.getInstance(); 6487171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt end.setTimeInMillis(now); 6499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int day = end.get(Calendar.DAY_OF_MONTH); 6509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.DAY_OF_MONTH, mPolicyResetDay); 6519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.HOUR_OF_DAY, 0); 6529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.MINUTE, 0); 6538c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt end.set(Calendar.SECOND, 0); 6548c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt end.set(Calendar.MILLISECOND, 0); 6559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (day >= mPolicyResetDay) { 6569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int month = end.get(Calendar.MONTH); 6579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (month == Calendar.DECEMBER) { 6589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.YEAR, end.get(Calendar.YEAR) + 1); 6599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt month = Calendar.JANUARY - 1; 6609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.set(Calendar.MONTH, month + 1); 6629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove! 6659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) { 6669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end = GregorianCalendar.getInstance(); 6677171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt end.setTimeInMillis(now); 6689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt end.add(Calendar.SECOND, TESTING_RESET_PERIOD_SEC); 6699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return end; 6719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private Calendar calculatePeriodStart(Calendar end) { 6739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar start = (Calendar)end.clone(); 6749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int month = end.get(Calendar.MONTH); 6759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (end.get(Calendar.MONTH) == Calendar.JANUARY) { 6769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt month = Calendar.DECEMBER + 1; 6779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.set(Calendar.YEAR, start.get(Calendar.YEAR) - 1); 6789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.set(Calendar.MONTH, month - 1); 6809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // TODO - remove!! 6829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) { 6839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start = (Calendar)end.clone(); 6849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt start.add(Calendar.SECOND, -TESTING_RESET_PERIOD_SEC); 6859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return start; 6879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void onResetAlarm() { 6905a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG || (mPolicyThreshold != 0)) { 6919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Slog.d(TAG, "onResetAlarm - last period had " + mRecorder.getPeriodRx(0) + 6929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt " bytes read and " + mRecorder.getPeriodTx(0) + " written"); 6939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 6949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6957171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long now = getBestTime(); 6969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 6977171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (mNtpActive || (mNtpServer == null)) { 6987171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Calendar end = calculatePeriodEnd(now); 6997171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt Calendar start = calculatePeriodStart(end); 7009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7017171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (mRecorder.setNextPeriod(start, end)) { 70205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt onPollAlarm(); 7037171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7047171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 7057171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mAlarmManager.cancel(mPendingResetIntent); 7067171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt long offset = end.getTimeInMillis() - now; 7077171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt // use Elapsed realtime so clock changes don't fool us. 7085a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, 7097171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt SystemClock.elapsedRealtime() + offset, 7107171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt mPendingResetIntent); 7117171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } else { 7125a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.d(TAG, "no authoritative time - not resetting period"); 7137171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7147171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7157171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7167171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 7177171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private void checkForAuthoritativeTime() { 7187171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (mNtpActive || (mNtpServer == null)) return; 7199e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 72005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // will try to get the ntp time and switch to it if found. 72105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // will also cache the time so we don't fetch it repeatedly. 72205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt getBestTime(); 7239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 725d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt private static final int MAX_NTP_CACHE_AGE_SEC = 60 * 60 * 24; // 1 day 72605d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt private static final int MAX_NTP_FETCH_WAIT = 10 * 1000; 727d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt private int mMaxNtpCacheAgeSec = MAX_NTP_CACHE_AGE_SEC; 72805d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt private long cachedNtp; 72905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt private long cachedNtpTimestamp; 73005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 7317171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt private long getBestTime() { 73205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt if (mNtpServer != null) { 73305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt if (mNtpActive) { 73405d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt long ntpAge = SystemClock.elapsedRealtime() - cachedNtpTimestamp; 735d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt if (ntpAge < mMaxNtpCacheAgeSec * 1000) { 736bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (VDBG) Slog.v(TAG, "using cached time"); 73705d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt return cachedNtp + ntpAge; 73805d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 73905d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 74005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt SntpClient client = new SntpClient(); 74105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt if (client.requestTime(mNtpServer, MAX_NTP_FETCH_WAIT)) { 74205d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt cachedNtp = client.getNtpTime(); 74305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt cachedNtpTimestamp = SystemClock.elapsedRealtime(); 74405d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt if (!mNtpActive) { 74505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt mNtpActive = true; 7465a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.d(TAG, "found Authoritative time - reseting alarm"); 74705d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget(); 74805d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 749bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (VDBG) Slog.v(TAG, "using Authoritative time: " + cachedNtp); 75005d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt return cachedNtp; 75105d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt } 7527171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 75305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt long time = System.currentTimeMillis(); 754bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (VDBG) Slog.v(TAG, "using User time: " + time); 75505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt mNtpActive = false; 7567171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return time; 7577171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 7587171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 7599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // records bytecount data for a given time and accumulates it into larger time windows 7609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // for logging and other purposes 7619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 7629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // since time can be changed (user or network action) we will have to track the time of the 7639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // last recording and deal with it. 7649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private static class DataRecorder { 7659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long[] mPeriodRxData; 7669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long[] mPeriodTxData; 7679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int mCurrentPeriod; 7689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int mPeriodCount; 7699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar mPeriodStart; 7719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Calendar mPeriodEnd; 7729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ThrottleService mParent; 7749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Context mContext; 775e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String mImsi = null; 776e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 777e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt TelephonyManager mTelephonyManager; 7789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt DataRecorder(Context context, ThrottleService parent) { 7809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mContext = context; 7819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mParent = parent; 7829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 783e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt mTelephonyManager = (TelephonyManager)mContext.getSystemService( 784e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt Context.TELEPHONY_SERVICE); 785e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 7869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 7879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodCount = 6; 7889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData = new long[mPeriodCount]; 7899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData = new long[mPeriodCount]; 7909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart = Calendar.getInstance(); 7929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd = Calendar.getInstance(); 7939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt retrieve(); 7959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 7979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 7987171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt boolean setNextPeriod(Calendar start, Calendar end) { 799e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // TODO - how would we deal with a dual-IMSI device? 800e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkForSubscriberId(); 8017171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt boolean startNewPeriod = true; 802bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt 80327fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt if (start.equals(mPeriodStart) && end.equals(mPeriodEnd)) { 80427fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt // same endpoints - keep collecting 8055a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) { 80627fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "same period (" + start.getTimeInMillis() + "," + 80727fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() +") - ammending data"); 8089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 80927fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt startNewPeriod = false; 81027fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } else { 8115a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) { 81227fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt if(start.equals(mPeriodEnd) || start.after(mPeriodEnd)) { 81327fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "next period (" + start.getTimeInMillis() + "," + 81427fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() + ") - old end was " + 81527fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodEnd.getTimeInMillis() + ", following"); 81627fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } else { 81727fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt Slog.d(TAG, "new period (" + start.getTimeInMillis() + "," + 81827fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt end.getTimeInMillis() + ") replacing old (" + 81927fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodStart.getTimeInMillis() + "," + 82027fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt mPeriodEnd.getTimeInMillis() + ")"); 82127fba6797b07583ef6c280bc287bf327e47f5e66Robert Greenwalt } 8229e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8239e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8249e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ++mCurrentPeriod; 8259e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mCurrentPeriod >= mPeriodCount) mCurrentPeriod = 0; 8269e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[mCurrentPeriod] = 0; 8279e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[mCurrentPeriod] = 0; 8289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt setPeriodStart(start); 8319e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt setPeriodEnd(end); 8329e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt record(); 8337171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return startNewPeriod; 8349e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8359e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8369e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public long getPeriodEnd() { 8379e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8389e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodEnd.getTimeInMillis(); 8399e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8429e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void setPeriodEnd(Calendar end) { 8439e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8449e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd = end; 8459e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8469e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public long getPeriodStart() { 8499e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodStart.getTimeInMillis(); 8519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8539e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void setPeriodStart(Calendar start) { 8559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart = start; 8579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt public int getPeriodCount() { 8619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodCount; 8639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void zeroData(int field) { 8679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt for(int period = 0; period<mPeriodCount; period++) { 8699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[period] = 0; 8709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[period] = 0; 8719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mCurrentPeriod = 0; 8739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 8779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // if time moves backward accumulate all read/write that's lost into the now 8789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // otherwise time moved forward. 8799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt void addData(long bytesRead, long bytesWritten) { 880e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkForSubscriberId(); 8817171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt 8829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 8839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[mCurrentPeriod] += bytesRead; 8849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[mCurrentPeriod] += bytesWritten; 8859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt record(); 8879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 8889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 889b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private File getDataFile() { 890b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File dataDir = Environment.getDataDirectory(); 891b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File throttleDir = new File(dataDir, "system/throttle"); 892b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt throttleDir.mkdirs(); 893e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String mImsi = mTelephonyManager.getSubscriberId(); 894e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File dataFile; 895e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi == null) { 896e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile = useMRUFile(throttleDir); 897bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (VDBG) Slog.v(TAG, "imsi not available yet, using " + dataFile); 898e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } else { 899e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt String imsiHash = Integer.toString(mImsi.hashCode()); 900e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile = new File(throttleDir, imsiHash); 901e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 902e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // touch the file so it's not LRU 903e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt dataFile.setLastModified(System.currentTimeMillis()); 904e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt checkAndDeleteLRUDataFile(throttleDir); 905b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return dataFile; 906b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 907b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 908e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt // TODO - get broadcast (TelephonyIntents.ACTION_SIM_STATE_CHANGED) instead of polling 909e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private void checkForSubscriberId() { 910e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi != null) return; 911e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 912e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt mImsi = mTelephonyManager.getSubscriberId(); 913e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (mImsi == null) return; 914e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 9155a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt if (VDBG) Slog.d(TAG, "finally have imsi - retreiving data"); 916e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt retrieve(); 917e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 918e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 919e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private final static int MAX_SIMS_SUPPORTED = 3; 920e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 921e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private void checkAndDeleteLRUDataFile(File dir) { 922e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File[] files = dir.listFiles(); 923e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 924e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (files.length <= MAX_SIMS_SUPPORTED) return; 925bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (DBG) Slog.d(TAG, "Too many data files"); 926e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt do { 927e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File oldest = null; 928e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt for (File f : files) { 929e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if ((oldest == null) || (oldest.lastModified() > f.lastModified())) { 930e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt oldest = f; 931e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 932e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 933e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (oldest == null) return; 934bf7de397279519e0144ceb7264003bc2accbb092Robert Greenwalt if (DBG) Slog.d(TAG, " deleting " + oldest); 935e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt oldest.delete(); 936e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt files = dir.listFiles(); 937e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } while (files.length > MAX_SIMS_SUPPORTED); 938e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 939e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 940e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt private File useMRUFile(File dir) { 941e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File newest = null; 942e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt File[] files = dir.listFiles(); 943e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 944e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt for (File f : files) { 945e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if ((newest == null) || (newest.lastModified() < f.lastModified())) { 946e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt newest = f; 947e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 948e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 949e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt if (newest == null) { 950e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt newest = new File(dir, "temp"); 951e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 952e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt return newest; 953e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt } 954e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 955e6e98823412275d869ec15d71fd11bba98417c45Robert Greenwalt 956b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private static final int DATA_FILE_VERSION = 1; 9579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 958b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt private void record() { 959b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt // 1 int version 9609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 1 int mPeriodCount 9619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13*6 long[PERIOD_COUNT] mPeriodRxData 9629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13*6 long[PERIOD_COUNT] mPeriodTxData 9639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 1 int mCurrentPeriod 9649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13 long periodStartMS 9659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt // 13 long periodEndMS 966b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt // 200 chars max 9679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt StringBuilder builder = new StringBuilder(); 968b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt builder.append(DATA_FILE_VERSION); 969b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt builder.append(":"); 9709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodCount); 9719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 972b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 9739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodRxData[i]); 9749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 9759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 976b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 9779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodTxData[i]); 9789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 9799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 9809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mCurrentPeriod); 9819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 9829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodStart.getTimeInMillis()); 9839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(":"); 9849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt builder.append(mPeriodEnd.getTimeInMillis()); 9859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 986b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt BufferedWriter out = null; 987b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 9887171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt out = new BufferedWriter(new FileWriter(getDataFile()), 256); 989b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt out.write(builder.toString()); 990b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (IOException e) { 991b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "Error writing data file"); 992b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 993b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } finally { 994b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (out != null) { 995b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 996b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt out.close(); 997b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (Exception e) {} 998b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 999b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 10009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10029e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt private void retrieve() { 100305d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt // clean out any old data first. If we fail to read we don't want old stuff 100405d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt zeroData(0); 100505d0673bfc5231f6dea4bc99627bbf44edf3a8d0Robert Greenwalt 1006b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt File f = getDataFile(); 1007b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt byte[] buffer; 1008b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt FileInputStream s = null; 1009b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 1010b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt buffer = new byte[(int)f.length()]; 1011b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s = new FileInputStream(f); 1012b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s.read(buffer); 1013b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (IOException e) { 1014b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "Error reading data file"); 1015b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 1016b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } finally { 1017b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (s != null) { 1018b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt try { 1019b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt s.close(); 1020b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } catch (Exception e) {} 1021b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1022b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1023b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt String data = new String(buffer); 10247171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (data == null || data.length() == 0) { 10257171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (DBG) Slog.d(TAG, "data file empty"); 10267171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return; 10277171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 10289e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 10299e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt String[] parsed = data.split(":"); 10309e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt int parsedUsed = 0; 1031b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (parsed.length < 6) { 1032b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "reading data file with insufficient length - ignoring"); 1033b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 1034b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 1035b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt 1036b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt if (Integer.parseInt(parsed[parsedUsed++]) != DATA_FILE_VERSION) { 1037b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt Slog.e(TAG, "reading data file with bad version - ignoring"); 1038b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt return; 1039b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt } 10409e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10419e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodCount = Integer.parseInt(parsed[parsedUsed++]); 10427171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt if (parsed.length != 5 + (2 * mPeriodCount)) { 10435a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt Slog.e(TAG, "reading data file with bad length (" + parsed.length + 10445a671d03e3abe522a761a43b0460f9f3816b14edRobert Greenwalt " != " + (5+(2*mPeriodCount)) + ") - ignoring"); 10457171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt return; 10467171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt } 10479e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10489e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData = new long[mPeriodCount]; 1049b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 10509e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodRxData[i] = Long.parseLong(parsed[parsedUsed++]); 10519e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10529e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData = new long[mPeriodCount]; 1053b8912f5481f79182184b628d7722e1a5b91b27f6Robert Greenwalt for(int i = 0; i < mPeriodCount; i++) { 10549e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodTxData[i] = Long.parseLong(parsed[parsedUsed++]); 10559e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10569e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mCurrentPeriod = Integer.parseInt(parsed[parsedUsed++]); 10579e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart = new GregorianCalendar(); 10589e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodStart.setTimeInMillis(Long.parseLong(parsed[parsedUsed++])); 10599e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd = new GregorianCalendar(); 10609e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPeriodEnd.setTimeInMillis(Long.parseLong(parsed[parsedUsed++])); 10619e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10629e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10639e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10649e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long getPeriodRx(int which) { 10659e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 10669e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which > mPeriodCount) return 0; 10679e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt which = mCurrentPeriod - which; 10689e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which < 0) which += mPeriodCount; 10699e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodRxData[which]; 10709e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10719e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10729e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt long getPeriodTx(int which) { 10739e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt synchronized (mParent) { 10749e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which > mPeriodCount) return 0; 10759e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt which = mCurrentPeriod - which; 10769e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (which < 0) which += mPeriodCount; 10779e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return mPeriodTxData[which]; 10789e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10799e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10809e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10819e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10829e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt @Override 10839e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10849e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt if (mContext.checkCallingOrSelfPermission( 10859e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt android.Manifest.permission.DUMP) 10869e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt != PackageManager.PERMISSION_GRANTED) { 10879e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Permission Denial: can't dump ThrottleService " + 10889e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt "from from pid=" + Binder.getCallingPid() + ", uid=" + 10899e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt Binder.getCallingUid()); 10909e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt return; 10919e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 10929e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println(); 10939e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt 10949e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("The threshold is " + mPolicyThreshold + 10959e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt ", after which you experince throttling to " + 10969e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mPolicyThrottleValue + "kbps"); 10979e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Current period is " + 10989e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt (mRecorder.getPeriodEnd() - mRecorder.getPeriodStart())/1000 + " seconds long " + 10997171ea8179e09270e4d6ab825a2320816eee39c5Robert Greenwalt "and ends in " + (getResetTime(mIface) - System.currentTimeMillis()) / 1000 + 11009e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt " seconds."); 11019e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println("Polling every " + mPolicyPollPeriodSec + " seconds"); 11028c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt pw.println("Current Throttle Index is " + mThrottleIndex); 1103d1055a250c00b0c2516ec406a8cf9a5ab1c0b7aeRobert Greenwalt pw.println("Max NTP Cache Age is " + mMaxNtpCacheAgeSec); 11048c7e609b530d5dcb34e02788958a84a99501c332Robert Greenwalt 11059e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt for (int i = 0; i < mRecorder.getPeriodCount(); i++) { 11069e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt pw.println(" Period[" + i + "] - read:" + mRecorder.getPeriodRx(i) + ", written:" + 11079e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt mRecorder.getPeriodTx(i)); 11089e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11099e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt } 11109e696c29f06d45d2891e1d38fd8d9033a9e21bb9Robert Greenwalt} 1111