Merge commit 'c2093636db6141426ca7fe88f07b30a284e36759' into kraken * commit 'c2093636db6141426ca7fe88f07b30a284e36759': Make ThrottleService more tamper resistant.
This commit is contained in:
@@ -30,6 +30,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.net.IThrottleManager;
|
import android.net.IThrottleManager;
|
||||||
|
import android.net.SntpClient;
|
||||||
import android.net.ThrottleManager;
|
import android.net.ThrottleManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
@@ -47,6 +48,7 @@ import android.provider.Settings;
|
|||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
import com.android.internal.telephony.TelephonyProperties;
|
import com.android.internal.telephony.TelephonyProperties;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
@@ -58,6 +60,7 @@ import java.io.IOException;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
// TODO - add comments - reference the ThrottleManager for public API
|
// TODO - add comments - reference the ThrottleManager for public API
|
||||||
@@ -73,7 +76,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1;
|
private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1;
|
||||||
private static final int TESTING_RESET_PERIOD_SEC = 60 * 3;
|
private static final int TESTING_RESET_PERIOD_SEC = 60 * 10;
|
||||||
private static final long TESTING_THRESHOLD = 1 * 1024 * 1024;
|
private static final long TESTING_THRESHOLD = 1 * 1024 * 1024;
|
||||||
|
|
||||||
private static final int PERIOD_COUNT = 6;
|
private static final int PERIOD_COUNT = 6;
|
||||||
@@ -114,10 +117,16 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
private static final int THROTTLE_INDEX_UNINITIALIZED = -1;
|
private static final int THROTTLE_INDEX_UNINITIALIZED = -1;
|
||||||
private static final int THROTTLE_INDEX_UNTHROTTLED = 0;
|
private static final int THROTTLE_INDEX_UNTHROTTLED = 0;
|
||||||
|
|
||||||
|
private static final String PROPERTIES_FILE = "/etc/gps.conf";
|
||||||
|
private String mNtpServer;
|
||||||
|
private boolean mNtpActive;
|
||||||
|
|
||||||
public ThrottleService(Context context) {
|
public ThrottleService(Context context) {
|
||||||
if (DBG) Slog.d(TAG, "Starting ThrottleService");
|
if (DBG) Slog.d(TAG, "Starting ThrottleService");
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
|
||||||
|
mNtpActive = false;
|
||||||
|
|
||||||
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
|
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
Intent pollIntent = new Intent(ACTION_POLL, null);
|
Intent pollIntent = new Intent(ACTION_POLL, null);
|
||||||
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
|
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
|
||||||
@@ -169,21 +178,33 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO - fetch for the iface
|
// TODO - fetch for the iface
|
||||||
|
// return time in the local, system wall time, correcting for the use of ntp
|
||||||
public synchronized long getResetTime(String iface) {
|
public synchronized long getResetTime(String iface) {
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
|
long resetTime = 0;
|
||||||
if (mRecorder != null) {
|
if (mRecorder != null) {
|
||||||
mRecorder.getPeriodEnd();
|
long bestEnd = mRecorder.getPeriodEnd();
|
||||||
|
long bestNow = getBestTime();
|
||||||
|
long localNow = System.currentTimeMillis();
|
||||||
|
|
||||||
|
resetTime = localNow + (bestEnd - bestNow);
|
||||||
}
|
}
|
||||||
return 0;
|
return resetTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - fetch for the iface
|
// TODO - fetch for the iface
|
||||||
|
// return time in the loca, system wall tiem, correcting for the use of ntp
|
||||||
public synchronized long getPeriodStartTime(String iface) {
|
public synchronized long getPeriodStartTime(String iface) {
|
||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
|
long startTime = 0;
|
||||||
if (mRecorder != null) {
|
if (mRecorder != null) {
|
||||||
mRecorder.getPeriodStart();
|
long bestStart = mRecorder.getPeriodStart();
|
||||||
|
long bestNow = getBestTime();
|
||||||
|
long localNow = System.currentTimeMillis();
|
||||||
|
|
||||||
|
startTime = localNow + (bestStart - bestNow);
|
||||||
}
|
}
|
||||||
return 0;
|
return startTime;
|
||||||
}
|
}
|
||||||
//TODO - a better name? getCliffByteCountThreshold?
|
//TODO - a better name? getCliffByteCountThreshold?
|
||||||
// TODO - fetch for the iface
|
// TODO - fetch for the iface
|
||||||
@@ -257,6 +278,23 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
|
|
||||||
mSettingsObserver = new SettingsObserver(mHandler, EVENT_POLICY_CHANGED);
|
mSettingsObserver = new SettingsObserver(mHandler, EVENT_POLICY_CHANGED);
|
||||||
mSettingsObserver.observe(mContext);
|
mSettingsObserver.observe(mContext);
|
||||||
|
|
||||||
|
FileInputStream stream = null;
|
||||||
|
try {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
File file = new File(PROPERTIES_FILE);
|
||||||
|
stream = new FileInputStream(file);
|
||||||
|
properties.load(stream);
|
||||||
|
mNtpServer = properties.getProperty("NTP_SERVER", null);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
|
||||||
|
} finally {
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -297,13 +335,6 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
|
|
||||||
// get policy
|
// get policy
|
||||||
mHandler.obtainMessage(EVENT_POLICY_CHANGED).sendToTarget();
|
mHandler.obtainMessage(EVENT_POLICY_CHANGED).sendToTarget();
|
||||||
|
|
||||||
// evaluate current conditions
|
|
||||||
mHandler.obtainMessage(EVENT_POLL_ALARM).sendToTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onSimChange() {
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for new policy info (threshold limit/value/etc)
|
// check for new policy info (threshold limit/value/etc)
|
||||||
@@ -311,15 +342,15 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
boolean testing = SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true");
|
boolean testing = SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true");
|
||||||
|
|
||||||
int pollingPeriod = mContext.getResources().getInteger(
|
int pollingPeriod = mContext.getResources().getInteger(
|
||||||
com.android.internal.R.integer.config_datause_polling_period_sec);
|
R.integer.config_datause_polling_period_sec);
|
||||||
mPolicyPollPeriodSec = Settings.Secure.getInt(mContext.getContentResolver(),
|
mPolicyPollPeriodSec = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||||
Settings.Secure.THROTTLE_POLLING_SEC, pollingPeriod);
|
Settings.Secure.THROTTLE_POLLING_SEC, pollingPeriod);
|
||||||
|
|
||||||
// TODO - remove testing stuff?
|
// TODO - remove testing stuff?
|
||||||
long defaultThreshold = mContext.getResources().getInteger(
|
long defaultThreshold = mContext.getResources().getInteger(
|
||||||
com.android.internal.R.integer.config_datause_threshold_bytes);
|
R.integer.config_datause_threshold_bytes);
|
||||||
int defaultValue = mContext.getResources().getInteger(
|
int defaultValue = mContext.getResources().getInteger(
|
||||||
com.android.internal.R.integer.config_datause_throttle_kbitsps);
|
R.integer.config_datause_throttle_kbitsps);
|
||||||
synchronized (ThrottleService.this) {
|
synchronized (ThrottleService.this) {
|
||||||
mPolicyThreshold = Settings.Secure.getLong(mContext.getContentResolver(),
|
mPolicyThreshold = Settings.Secure.getLong(mContext.getContentResolver(),
|
||||||
Settings.Secure.THROTTLE_THRESHOLD_BYTES, defaultThreshold);
|
Settings.Secure.THROTTLE_THRESHOLD_BYTES, defaultThreshold);
|
||||||
@@ -340,8 +371,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
Settings.Secure.THROTTLE_RESET_DAY, mPolicyResetDay);
|
Settings.Secure.THROTTLE_RESET_DAY, mPolicyResetDay);
|
||||||
}
|
}
|
||||||
mIface = mContext.getResources().getString(
|
mIface = mContext.getResources().getString(R.string.config_datause_iface);
|
||||||
com.android.internal.R.string.config_datause_iface);
|
|
||||||
synchronized (ThrottleService.this) {
|
synchronized (ThrottleService.this) {
|
||||||
if (mIface == null) {
|
if (mIface == null) {
|
||||||
mPolicyThreshold = 0;
|
mPolicyThreshold = 0;
|
||||||
@@ -349,7 +379,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int defaultNotificationType = mContext.getResources().getInteger(
|
int defaultNotificationType = mContext.getResources().getInteger(
|
||||||
com.android.internal.R.integer.config_datause_notification_type);
|
R.integer.config_datause_notification_type);
|
||||||
mPolicyNotificationsAllowedMask = Settings.Secure.getInt(mContext.getContentResolver(),
|
mPolicyNotificationsAllowedMask = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||||
Settings.Secure.THROTTLE_NOTIFICATION_TYPE, defaultNotificationType);
|
Settings.Secure.THROTTLE_NOTIFICATION_TYPE, defaultNotificationType);
|
||||||
|
|
||||||
@@ -369,6 +399,9 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
private void onPollAlarm() {
|
private void onPollAlarm() {
|
||||||
long now = SystemClock.elapsedRealtime();
|
long now = SystemClock.elapsedRealtime();
|
||||||
long next = now + mPolicyPollPeriodSec*1000;
|
long next = now + mPolicyPollPeriodSec*1000;
|
||||||
|
|
||||||
|
checkForAuthoritativeTime();
|
||||||
|
|
||||||
long incRead = 0;
|
long incRead = 0;
|
||||||
long incWrite = 0;
|
long incWrite = 0;
|
||||||
try {
|
try {
|
||||||
@@ -407,8 +440,8 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION);
|
Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION);
|
||||||
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx);
|
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx);
|
||||||
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx);
|
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx);
|
||||||
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, mRecorder.getPeriodStart());
|
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, ThrottleService.this.getPeriodStartTime(mIface));
|
||||||
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, mRecorder.getPeriodEnd());
|
broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, ThrottleService.this.getResetTime(mIface));
|
||||||
mContext.sendStickyBroadcast(broadcast);
|
mContext.sendStickyBroadcast(broadcast);
|
||||||
|
|
||||||
mAlarmManager.cancel(mPendingPollIntent);
|
mAlarmManager.cancel(mPendingPollIntent);
|
||||||
@@ -417,8 +450,15 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
|
|
||||||
private void checkThrottleAndPostNotification(long currentTotal) {
|
private void checkThrottleAndPostNotification(long currentTotal) {
|
||||||
// is throttling enabled?
|
// is throttling enabled?
|
||||||
if (mPolicyThreshold == 0)
|
if (mPolicyThreshold == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// have we spoken with an ntp server yet?
|
||||||
|
// this is controversial, but we'd rather err towards not throttling
|
||||||
|
if ((mNtpServer != null) && !mNtpActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check if we need to throttle
|
// check if we need to throttle
|
||||||
if (currentTotal > mPolicyThreshold) {
|
if (currentTotal > mPolicyThreshold) {
|
||||||
@@ -434,12 +474,11 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
Slog.e(TAG, "error setting Throttle: " + e);
|
Slog.e(TAG, "error setting Throttle: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNotificationManager.cancel(com.android.internal.R.drawable.
|
mNotificationManager.cancel(R.drawable.stat_sys_throttled);
|
||||||
stat_sys_throttled);
|
|
||||||
|
|
||||||
postNotification(com.android.internal.R.string.throttled_notification_title,
|
postNotification(R.string.throttled_notification_title,
|
||||||
com.android.internal.R.string.throttled_notification_message,
|
R.string.throttled_notification_message,
|
||||||
com.android.internal.R.drawable.stat_sys_throttled,
|
R.drawable.stat_sys_throttled,
|
||||||
Notification.FLAG_ONGOING_EVENT);
|
Notification.FLAG_ONGOING_EVENT);
|
||||||
|
|
||||||
Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION);
|
Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION);
|
||||||
@@ -469,19 +508,15 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
if ((currentTotal > warningThreshold) && (currentTotal > mPolicyThreshold/4)) {
|
if ((currentTotal > warningThreshold) && (currentTotal > mPolicyThreshold/4)) {
|
||||||
if (mWarningNotificationSent == false) {
|
if (mWarningNotificationSent == false) {
|
||||||
mWarningNotificationSent = true;
|
mWarningNotificationSent = true;
|
||||||
mNotificationManager.cancel(com.android.internal.R.drawable.
|
mNotificationManager.cancel(R.drawable.stat_sys_throttled);
|
||||||
stat_sys_throttled);
|
postNotification(R.string.throttle_warning_notification_title,
|
||||||
postNotification(com.android.internal.R.string.
|
R.string.throttle_warning_notification_message,
|
||||||
throttle_warning_notification_title,
|
R.drawable.stat_sys_throttled,
|
||||||
com.android.internal.R.string.
|
|
||||||
throttle_warning_notification_message,
|
|
||||||
com.android.internal.R.drawable.stat_sys_throttled,
|
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mWarningNotificationSent == true) {
|
if (mWarningNotificationSent == true) {
|
||||||
mNotificationManager.cancel(com.android.internal.R.drawable.
|
mNotificationManager.cancel(R.drawable.stat_sys_throttled);
|
||||||
stat_sys_throttled);
|
|
||||||
mWarningNotificationSent =false;
|
mWarningNotificationSent =false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,12 +564,13 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1);
|
broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1);
|
||||||
mContext.sendStickyBroadcast(broadcast);
|
mContext.sendStickyBroadcast(broadcast);
|
||||||
}
|
}
|
||||||
mNotificationManager.cancel(com.android.internal.R.drawable.stat_sys_throttled);
|
mNotificationManager.cancel(R.drawable.stat_sys_throttled);
|
||||||
mWarningNotificationSent = false;
|
mWarningNotificationSent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Calendar calculatePeriodEnd() {
|
private Calendar calculatePeriodEnd(long now) {
|
||||||
Calendar end = GregorianCalendar.getInstance();
|
Calendar end = GregorianCalendar.getInstance();
|
||||||
|
end.setTimeInMillis(now);
|
||||||
int day = end.get(Calendar.DAY_OF_MONTH);
|
int day = end.get(Calendar.DAY_OF_MONTH);
|
||||||
end.set(Calendar.DAY_OF_MONTH, mPolicyResetDay);
|
end.set(Calendar.DAY_OF_MONTH, mPolicyResetDay);
|
||||||
end.set(Calendar.HOUR_OF_DAY, 0);
|
end.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
@@ -553,6 +589,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
// TODO - remove!
|
// TODO - remove!
|
||||||
if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) {
|
if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) {
|
||||||
end = GregorianCalendar.getInstance();
|
end = GregorianCalendar.getInstance();
|
||||||
|
end.setTimeInMillis(now);
|
||||||
end.add(Calendar.SECOND, TESTING_RESET_PERIOD_SEC);
|
end.add(Calendar.SECOND, TESTING_RESET_PERIOD_SEC);
|
||||||
}
|
}
|
||||||
return end;
|
return end;
|
||||||
@@ -580,19 +617,59 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
" bytes read and " + mRecorder.getPeriodTx(0) + " written");
|
" bytes read and " + mRecorder.getPeriodTx(0) + " written");
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar end = calculatePeriodEnd();
|
long now = getBestTime();
|
||||||
Calendar start = calculatePeriodStart(end);
|
|
||||||
|
|
||||||
clearThrottleAndNotification();
|
if (mNtpActive || (mNtpServer == null)) {
|
||||||
|
Calendar end = calculatePeriodEnd(now);
|
||||||
|
Calendar start = calculatePeriodStart(end);
|
||||||
|
|
||||||
mRecorder.setNextPeriod(start,end);
|
if (mRecorder.setNextPeriod(start, end)) {
|
||||||
|
clearThrottleAndNotification();
|
||||||
|
}
|
||||||
|
|
||||||
mAlarmManager.cancel(mPendingResetIntent);
|
mAlarmManager.cancel(mPendingResetIntent);
|
||||||
mAlarmManager.set(AlarmManager.RTC_WAKEUP, end.getTimeInMillis(),
|
long offset = end.getTimeInMillis() - now;
|
||||||
mPendingResetIntent);
|
// use Elapsed realtime so clock changes don't fool us.
|
||||||
|
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
|
SystemClock.elapsedRealtime() + offset,
|
||||||
|
mPendingResetIntent);
|
||||||
|
} else {
|
||||||
|
if (DBG) Slog.d(TAG, "no authoritative time - not resetting period");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkForAuthoritativeTime() {
|
||||||
|
if (mNtpActive || (mNtpServer == null)) return;
|
||||||
|
|
||||||
|
SntpClient client = new SntpClient();
|
||||||
|
if (client.requestTime(mNtpServer, 10000)) {
|
||||||
|
mNtpActive = true;
|
||||||
|
if (DBG) Slog.d(TAG, "found Authoritative time - reseting alarm");
|
||||||
|
mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getBestTime() {
|
||||||
|
SntpClient client = new SntpClient();
|
||||||
|
|
||||||
|
long time;
|
||||||
|
if ((mNtpServer != null) && client.requestTime(mNtpServer, 10000)) {
|
||||||
|
time = client.getNtpTime() ;
|
||||||
|
if (!mNtpActive) {
|
||||||
|
mNtpActive = true;
|
||||||
|
if (DBG) Slog.d(TAG, "found Authoritative time - reseting alarm");
|
||||||
|
mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
|
||||||
|
}
|
||||||
|
if (DBG) Slog.d(TAG, "using Authoritative time: " + time);
|
||||||
|
} else {
|
||||||
|
time = System.currentTimeMillis();
|
||||||
|
if (DBG) Slog.d(TAG, "using User time: " + time);
|
||||||
|
mNtpActive = false;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
// records bytecount data for a given time and accumulates it into larger time windows
|
// records bytecount data for a given time and accumulates it into larger time windows
|
||||||
// for logging and other purposes
|
// for logging and other purposes
|
||||||
//
|
//
|
||||||
@@ -633,16 +710,16 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNextPeriod(Calendar start, Calendar end) {
|
boolean setNextPeriod(Calendar start, Calendar end) {
|
||||||
// TODO - how would we deal with a dual-IMSI device?
|
// TODO - how would we deal with a dual-IMSI device?
|
||||||
checkForSubscriberId();
|
checkForSubscriberId();
|
||||||
|
boolean startNewPeriod = true;
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, "setting next period to " + start.getTimeInMillis() +
|
Slog.d(TAG, "setting next period to " + start.getTimeInMillis() +
|
||||||
" --until-- " + end.getTimeInMillis());
|
" --until-- " + end.getTimeInMillis());
|
||||||
}
|
}
|
||||||
// if we roll back in time to a previous period, toss out the current data
|
// if we rolled back in time, toss out
|
||||||
// if we roll forward to the next period, advance to the next
|
// if we rolled foward, advance to the next
|
||||||
|
|
||||||
if (end.before(mPeriodStart)) {
|
if (end.before(mPeriodStart)) {
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, " old start was " + mPeriodStart.getTimeInMillis() + ", wiping");
|
Slog.d(TAG, " old start was " + mPeriodStart.getTimeInMillis() + ", wiping");
|
||||||
@@ -662,11 +739,13 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
mPeriodTxData[mCurrentPeriod] = 0;
|
mPeriodTxData[mCurrentPeriod] = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
startNewPeriod = false;
|
||||||
if (DBG) Slog.d(TAG, " we fit - ammending to last period");
|
if (DBG) Slog.d(TAG, " we fit - ammending to last period");
|
||||||
}
|
}
|
||||||
setPeriodStart(start);
|
setPeriodStart(start);
|
||||||
setPeriodEnd(end);
|
setPeriodEnd(end);
|
||||||
record();
|
record();
|
||||||
|
return startNewPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPeriodEnd() {
|
public long getPeriodEnd() {
|
||||||
@@ -714,6 +793,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
// otherwise time moved forward.
|
// otherwise time moved forward.
|
||||||
void addData(long bytesRead, long bytesWritten) {
|
void addData(long bytesRead, long bytesWritten) {
|
||||||
checkForSubscriberId();
|
checkForSubscriberId();
|
||||||
|
|
||||||
synchronized (mParent) {
|
synchronized (mParent) {
|
||||||
mPeriodRxData[mCurrentPeriod] += bytesRead;
|
mPeriodRxData[mCurrentPeriod] += bytesRead;
|
||||||
mPeriodTxData[mCurrentPeriod] += bytesWritten;
|
mPeriodTxData[mCurrentPeriod] += bytesWritten;
|
||||||
@@ -817,11 +897,10 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
builder.append(mPeriodStart.getTimeInMillis());
|
builder.append(mPeriodStart.getTimeInMillis());
|
||||||
builder.append(":");
|
builder.append(":");
|
||||||
builder.append(mPeriodEnd.getTimeInMillis());
|
builder.append(mPeriodEnd.getTimeInMillis());
|
||||||
builder.append(":");
|
|
||||||
|
|
||||||
BufferedWriter out = null;
|
BufferedWriter out = null;
|
||||||
try {
|
try {
|
||||||
out = new BufferedWriter(new FileWriter(getDataFile()),256);
|
out = new BufferedWriter(new FileWriter(getDataFile()), 256);
|
||||||
out.write(builder.toString());
|
out.write(builder.toString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "Error writing data file");
|
Slog.e(TAG, "Error writing data file");
|
||||||
@@ -854,7 +933,10 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
String data = new String(buffer);
|
String data = new String(buffer);
|
||||||
if (data == null || data.length() == 0) return;
|
if (data == null || data.length() == 0) {
|
||||||
|
if (DBG) Slog.d(TAG, "data file empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
synchronized (mParent) {
|
synchronized (mParent) {
|
||||||
String[] parsed = data.split(":");
|
String[] parsed = data.split(":");
|
||||||
int parsedUsed = 0;
|
int parsedUsed = 0;
|
||||||
@@ -869,7 +951,10 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPeriodCount = Integer.parseInt(parsed[parsedUsed++]);
|
mPeriodCount = Integer.parseInt(parsed[parsedUsed++]);
|
||||||
if (parsed.length != 4 + (2 * mPeriodCount)) return;
|
if (parsed.length != 5 + (2 * mPeriodCount)) {
|
||||||
|
Slog.e(TAG, "reading data file with bad length ("+parsed.length+" != "+(4 + (2*mPeriodCount))+") - ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mPeriodRxData = new long[mPeriodCount];
|
mPeriodRxData = new long[mPeriodCount];
|
||||||
for(int i = 0; i < mPeriodCount; i++) {
|
for(int i = 0; i < mPeriodCount; i++) {
|
||||||
@@ -922,7 +1007,7 @@ public class ThrottleService extends IThrottleManager.Stub {
|
|||||||
mPolicyThrottleValue + "kbps");
|
mPolicyThrottleValue + "kbps");
|
||||||
pw.println("Current period is " +
|
pw.println("Current period is " +
|
||||||
(mRecorder.getPeriodEnd() - mRecorder.getPeriodStart())/1000 + " seconds long " +
|
(mRecorder.getPeriodEnd() - mRecorder.getPeriodStart())/1000 + " seconds long " +
|
||||||
"and ends in " + (mRecorder.getPeriodEnd() - System.currentTimeMillis()) / 1000 +
|
"and ends in " + (getResetTime(mIface) - System.currentTimeMillis()) / 1000 +
|
||||||
" seconds.");
|
" seconds.");
|
||||||
pw.println("Polling every " + mPolicyPollPeriodSec + " seconds");
|
pw.println("Polling every " + mPolicyPollPeriodSec + " seconds");
|
||||||
pw.println("Current Throttle Index is " + mThrottleIndex);
|
pw.println("Current Throttle Index is " + mThrottleIndex);
|
||||||
|
|||||||
Reference in New Issue
Block a user