/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server;

import com.android.internal.R;
import com.android.internal.telephony.TelephonyProperties;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.INetworkManagementEventObserver;
import android.net.IThrottleManager;
import android.net.NetworkStats;
import android.net.ThrottleManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.NtpTrustedTime;
import android.util.Slog;
import android.util.TrustedTime;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

// TODO - add comments - reference the ThrottleManager for public API
public class ThrottleService extends IThrottleManager.Stub {

    private static final String TESTING_ENABLED_PROPERTY = "persist.throttle.testing";

    private static final String TAG = "ThrottleService";
    private static final boolean DBG = true;
    private static final boolean VDBG = false;
    private Handler mHandler;
    private HandlerThread mThread;

    private Context mContext;

    private static final int INITIAL_POLL_DELAY_SEC = 90;
    private static final int TESTING_POLLING_PERIOD_SEC = 60 * 1;
    private static final int TESTING_RESET_PERIOD_SEC = 60 * 10;
    private static final long TESTING_THRESHOLD = 1 * 1024 * 1024;

    private static final long MAX_NTP_CACHE_AGE = 24 * 60 * 60 * 1000;
    private static final long MAX_NTP_FETCH_WAIT = 20 * 1000;

    private long mMaxNtpCacheAge = MAX_NTP_CACHE_AGE;

    private int mPolicyPollPeriodSec;
    private AtomicLong mPolicyThreshold;
    private AtomicInteger mPolicyThrottleValue;
    private int mPolicyResetDay; // 1-28
    private int mPolicyNotificationsAllowedMask;

    private long mLastRead; // read byte count from last poll
    private long mLastWrite; // write byte count from last poll

    private static final String ACTION_POLL = "com.android.server.ThrottleManager.action.POLL";
    private static int POLL_REQUEST = 0;
    private PendingIntent mPendingPollIntent;
    private static final String ACTION_RESET = "com.android.server.ThorottleManager.action.RESET";
    private static int RESET_REQUEST = 1;
    private PendingIntent mPendingResetIntent;

    private INetworkManagementService mNMService;
    private AlarmManager mAlarmManager;
    private NotificationManager mNotificationManager;

    private DataRecorder mRecorder;

    private String mIface;

    private static final int NOTIFICATION_WARNING   = 2;

    private Notification mThrottlingNotification;
    private boolean mWarningNotificationSent = false;

    private InterfaceObserver mInterfaceObserver;
    private SettingsObserver mSettingsObserver;

    private AtomicInteger mThrottleIndex; // 0 for none, 1 for first throttle val, 2 for next, etc
    private static final int THROTTLE_INDEX_UNINITIALIZED = -1;
    private static final int THROTTLE_INDEX_UNTHROTTLED   =  0;

    private static final String PROPERTIES_FILE = "/etc/gps.conf";

    private Intent mPollStickyBroadcast;

    private TrustedTime mTime;

    private static INetworkManagementService getNetworkManagementService() {
        final IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        return INetworkManagementService.Stub.asInterface(b);
    }

    public ThrottleService(Context context) {
        // TODO: move to using cached NtpTrustedTime
        this(context, getNetworkManagementService(), new NtpTrustedTime(),
                context.getResources().getString(R.string.config_datause_iface));
    }

    public ThrottleService(Context context, INetworkManagementService nmService, TrustedTime time,
            String iface) {
        if (VDBG) Slog.v(TAG, "Starting ThrottleService");
        mContext = context;

        mPolicyThreshold = new AtomicLong();
        mPolicyThrottleValue = new AtomicInteger();
        mThrottleIndex = new AtomicInteger();

        mIface = iface;
        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
        Intent pollIntent = new Intent(ACTION_POLL, null);
        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
        Intent resetIntent = new Intent(ACTION_RESET, null);
        mPendingResetIntent = PendingIntent.getBroadcast(mContext, RESET_REQUEST, resetIntent, 0);

        mNMService = nmService;
        mTime = time;

        mNotificationManager = (NotificationManager)mContext.getSystemService(
                Context.NOTIFICATION_SERVICE);
    }

    private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
        private int mMsg;
        private Handler mHandler;
        private String mIface;

        InterfaceObserver(Handler handler, int msg, String iface) {
            super();
            mHandler = handler;
            mMsg = msg;
            mIface = iface;
        }

        public void interfaceLinkStatusChanged(String iface, boolean link) {
            if (link) {
                if (TextUtils.equals(iface, mIface)) {
                    mHandler.obtainMessage(mMsg).sendToTarget();
                }
            }
        }

        public void interfaceAdded(String iface) {
            // TODO - an interface added in the UP state should also trigger a StatusChanged
            // notification..
            if (TextUtils.equals(iface, mIface)) {
                mHandler.obtainMessage(mMsg).sendToTarget();
            }
        }

        public void interfaceRemoved(String iface) {}
    }


    private static class SettingsObserver extends ContentObserver {
        private int mMsg;
        private Handler mHandler;
        SettingsObserver(Handler handler, int msg) {
            super(handler);
            mHandler = handler;
            mMsg = msg;
        }

        void register(Context context) {
            ContentResolver resolver = context.getContentResolver();
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_POLLING_SEC), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_THRESHOLD_BYTES), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_VALUE_KBITSPS), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_RESET_DAY), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_NOTIFICATION_TYPE), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_HELP_URI), false, this);
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC), false, this);
        }

        void unregister(Context context) {
            final ContentResolver resolver = context.getContentResolver();
            resolver.unregisterContentObserver(this);
        }

        @Override
        public void onChange(boolean selfChange) {
            mHandler.obtainMessage(mMsg).sendToTarget();
        }
    }

    private void enforceAccessPermission() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE,
                "ThrottleService");
    }

    private long ntpToWallTime(long ntpTime) {
        // get time quickly without worrying about trusted state
        long bestNow = mTime.hasCache() ? mTime.currentTimeMillis()
                : System.currentTimeMillis();
        long localNow = System.currentTimeMillis();
        return localNow + (ntpTime - bestNow);
    }

    // TODO - fetch for the iface
    // return time in the local, system wall time, correcting for the use of ntp

    public long getResetTime(String iface) {
        enforceAccessPermission();
        long resetTime = 0;
        if (mRecorder != null) {
            resetTime = mRecorder.getPeriodEnd();
        }
        resetTime = ntpToWallTime(resetTime);
        return resetTime;
    }

    // TODO - fetch for the iface
    // return time in the local, system wall time, correcting for the use of ntp
    public long getPeriodStartTime(String iface) {
        long startTime = 0;
        enforceAccessPermission();
        if (mRecorder != null) {
            startTime = mRecorder.getPeriodStart();
        }
        startTime = ntpToWallTime(startTime);
        return startTime;
    }
    //TODO - a better name?  getCliffByteCountThreshold?
    // TODO - fetch for the iface
    public long getCliffThreshold(String iface, int cliff) {
        enforceAccessPermission();
        if (cliff == 1) {
           return mPolicyThreshold.get();
        }
        return 0;
    }
    // TODO - a better name? getThrottleRate?
    // TODO - fetch for the iface
    public int getCliffLevel(String iface, int cliff) {
        enforceAccessPermission();
        if (cliff == 1) {
            return mPolicyThrottleValue.get();
        }
        return 0;
    }

    public String getHelpUri() {
        enforceAccessPermission();
        return Settings.Secure.getString(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_HELP_URI);
    }

    // TODO - fetch for the iface
    public long getByteCount(String iface, int dir, int period, int ago) {
        enforceAccessPermission();
        if ((period == ThrottleManager.PERIOD_CYCLE) && (mRecorder != null)) {
            if (dir == ThrottleManager.DIRECTION_TX) return mRecorder.getPeriodTx(ago);
            if (dir == ThrottleManager.DIRECTION_RX) return mRecorder.getPeriodRx(ago);
        }
        return 0;
    }

    // TODO - a better name - getCurrentThrottleRate?
    // TODO - fetch for the iface
    public int getThrottle(String iface) {
        enforceAccessPermission();
        if (mThrottleIndex.get() == 1) {
            return mPolicyThrottleValue.get();
        }
        return 0;
    }

    void systemReady() {
        if (VDBG) Slog.v(TAG, "systemReady");
        mContext.registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    dispatchPoll();
                }
            }, new IntentFilter(ACTION_POLL));

        mContext.registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    dispatchReset();
                }
            }, new IntentFilter(ACTION_RESET));

        FileInputStream stream = null;
        try {
            Properties properties = new Properties();
            File file = new File(PROPERTIES_FILE);
            stream = new FileInputStream(file);
            properties.load(stream);
            final String ntpServer = properties.getProperty("NTP_SERVER", null);
            if (mTime instanceof NtpTrustedTime) {
                ((NtpTrustedTime) mTime).setNtpServer(ntpServer, MAX_NTP_FETCH_WAIT);
            }
        } catch (IOException e) {
            Slog.e(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (Exception e) {}
            }
        }

        // use a new thread as we don't want to stall the system for file writes
        mThread = new HandlerThread(TAG);
        mThread.start();
        mHandler = new MyHandler(mThread.getLooper());
        mHandler.obtainMessage(EVENT_REBOOT_RECOVERY).sendToTarget();

        mInterfaceObserver = new InterfaceObserver(mHandler, EVENT_IFACE_UP, mIface);
        try {
            mNMService.registerObserver(mInterfaceObserver);
        } catch (RemoteException e) {
            Slog.e(TAG, "Could not register InterfaceObserver " + e);
        }

        mSettingsObserver = new SettingsObserver(mHandler, EVENT_POLICY_CHANGED);
        mSettingsObserver.register(mContext);
    }

    void shutdown() {
        // TODO: eventually connect with ShutdownThread to persist stats during
        // graceful shutdown.

        if (mThread != null) {
            mThread.quit();
        }

        if (mSettingsObserver != null) {
            mSettingsObserver.unregister(mContext);
        }

        if (mPollStickyBroadcast != null) {
            mContext.removeStickyBroadcast(mPollStickyBroadcast);
        }
    }

    void dispatchPoll() {
        mHandler.obtainMessage(EVENT_POLL_ALARM).sendToTarget();
    }

    void dispatchReset() {
        mHandler.obtainMessage(EVENT_RESET_ALARM).sendToTarget();
    }

    private static final int EVENT_REBOOT_RECOVERY = 0;
    private static final int EVENT_POLICY_CHANGED  = 1;
    private static final int EVENT_POLL_ALARM      = 2;
    private static final int EVENT_RESET_ALARM     = 3;
    private static final int EVENT_IFACE_UP        = 4;
    private class MyHandler extends Handler {
        public MyHandler(Looper l) {
            super(l);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case EVENT_REBOOT_RECOVERY:
                onRebootRecovery();
                break;
            case EVENT_POLICY_CHANGED:
                onPolicyChanged();
                break;
            case EVENT_POLL_ALARM:
                onPollAlarm();
                break;
            case EVENT_RESET_ALARM:
                onResetAlarm();
                break;
            case EVENT_IFACE_UP:
                onIfaceUp();
            }
        }

        private void onRebootRecovery() {
            if (VDBG) Slog.v(TAG, "onRebootRecovery");
            // check for sim change TODO
            // reregister for notification of policy change

            mThrottleIndex.set(THROTTLE_INDEX_UNINITIALIZED);

            mRecorder = new DataRecorder(mContext, ThrottleService.this);

            // get policy
            mHandler.obtainMessage(EVENT_POLICY_CHANGED).sendToTarget();

            // if we poll now we won't have network connectivity or even imsi access
            // queue up a poll to happen in a little while - after ntp and imsi are avail
            // TODO - make this callback based (ie, listen for notificaitons)
            mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_POLL_ALARM),
                    INITIAL_POLL_DELAY_SEC * 1000);
        }

        // check for new policy info (threshold limit/value/etc)
        private void onPolicyChanged() {
            boolean testing = SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true");

            int pollingPeriod = mContext.getResources().getInteger(
                    R.integer.config_datause_polling_period_sec);
            mPolicyPollPeriodSec = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_POLLING_SEC, pollingPeriod);

            // TODO - remove testing stuff?
            long defaultThreshold = mContext.getResources().getInteger(
                    R.integer.config_datause_threshold_bytes);
            int defaultValue = mContext.getResources().getInteger(
                    R.integer.config_datause_throttle_kbitsps);
            long threshold = Settings.Secure.getLong(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_THRESHOLD_BYTES, defaultThreshold);
            int value = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_VALUE_KBITSPS, defaultValue);

            mPolicyThreshold.set(threshold);
            mPolicyThrottleValue.set(value);
            if (testing) {
                mPolicyPollPeriodSec = TESTING_POLLING_PERIOD_SEC;
                mPolicyThreshold.set(TESTING_THRESHOLD);
            }

            mPolicyResetDay = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_RESET_DAY, -1);
            if (mPolicyResetDay == -1 ||
                    ((mPolicyResetDay < 1) || (mPolicyResetDay > 28))) {
                Random g = new Random();
                mPolicyResetDay = 1 + g.nextInt(28); // 1-28
                Settings.Secure.putInt(mContext.getContentResolver(),
                Settings.Secure.THROTTLE_RESET_DAY, mPolicyResetDay);
            }
            if (mIface == null) {
                mPolicyThreshold.set(0);
            }

            int defaultNotificationType = mContext.getResources().getInteger(
                    R.integer.config_datause_notification_type);
            mPolicyNotificationsAllowedMask = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_NOTIFICATION_TYPE, defaultNotificationType);

            final int maxNtpCacheAgeSec = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.THROTTLE_MAX_NTP_CACHE_AGE_SEC,
                    (int) (MAX_NTP_CACHE_AGE / 1000));
            mMaxNtpCacheAge = maxNtpCacheAgeSec * 1000;

            if (VDBG || (mPolicyThreshold.get() != 0)) {
                Slog.d(TAG, "onPolicyChanged testing=" + testing +", period=" +
                        mPolicyPollPeriodSec + ", threshold=" + mPolicyThreshold.get() +
                        ", value=" + mPolicyThrottleValue.get() + ", resetDay=" + mPolicyResetDay +
                        ", noteType=" + mPolicyNotificationsAllowedMask + ", mMaxNtpCacheAge=" +
                        mMaxNtpCacheAge);
            }

            // force updates
            mThrottleIndex.set(THROTTLE_INDEX_UNINITIALIZED);

            onResetAlarm();

            onPollAlarm();

            Intent broadcast = new Intent(ThrottleManager.POLICY_CHANGED_ACTION);
            mContext.sendBroadcast(broadcast);
        }

        private void onPollAlarm() {
            long now = SystemClock.elapsedRealtime();
            long next = now + mPolicyPollPeriodSec * 1000;

            // when trusted cache outdated, try refreshing
            if (mTime.getCacheAge() > mMaxNtpCacheAge) {
                if (mTime.forceRefresh()) {
                    if (VDBG) Slog.d(TAG, "updated trusted time, reseting alarm");
                    dispatchReset();
                }
            }

            long incRead = 0;
            long incWrite = 0;
            try {
                final NetworkStats stats = mNMService.getNetworkStatsSummary();
                final int index = stats.findIndex(mIface, NetworkStats.UID_ALL);

                if (index != -1) {
                    incRead = stats.rx[index] - mLastRead;
                    incWrite = stats.tx[index] - mLastWrite;
                } else {
                    // missing iface, assume stats are 0
                    Slog.w(TAG, "unable to find stats for iface " + mIface);
                }

                // handle iface resets - on some device the 3g iface comes and goes and gets
                // totals reset to 0.  Deal with it
                if ((incRead < 0) || (incWrite < 0)) {
                    incRead += mLastRead;
                    incWrite += mLastWrite;
                    mLastRead = 0;
                    mLastWrite = 0;
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "got remoteException in onPollAlarm:" + e);
            }
            // don't count this data if we're roaming.
            boolean roaming = "true".equals(
                    SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING));
            if (!roaming) {
                mRecorder.addData(incRead, incWrite);
            }

            long periodRx = mRecorder.getPeriodRx(0);
            long periodTx = mRecorder.getPeriodTx(0);
            long total = periodRx + periodTx;
            if (VDBG || (mPolicyThreshold.get() != 0)) {
                Slog.d(TAG, "onPollAlarm - roaming =" + roaming +
                        ", read =" + incRead + ", written =" + incWrite + ", new total =" + total);
            }
            mLastRead += incRead;
            mLastWrite += incWrite;

            checkThrottleAndPostNotification(total);

            Intent broadcast = new Intent(ThrottleManager.THROTTLE_POLL_ACTION);
            broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_READ, periodRx);
            broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_WRITE, periodTx);
            broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_START, getPeriodStartTime(mIface));
            broadcast.putExtra(ThrottleManager.EXTRA_CYCLE_END, getResetTime(mIface));
            mContext.sendStickyBroadcast(broadcast);
            mPollStickyBroadcast = broadcast;

            mAlarmManager.cancel(mPendingPollIntent);
            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
        }

        private void onIfaceUp() {
            // if we were throttled before, be sure and set it again - the iface went down
            // (and may have disappeared all together) and these settings were lost
            if (mThrottleIndex.get() == 1) {
                try {
                    mNMService.setInterfaceThrottle(mIface, -1, -1);
                    mNMService.setInterfaceThrottle(mIface,
                            mPolicyThrottleValue.get(), mPolicyThrottleValue.get());
                } catch (Exception e) {
                    Slog.e(TAG, "error setting Throttle: " + e);
                }
            }
        }

        private void checkThrottleAndPostNotification(long currentTotal) {
            // is throttling enabled?
            long threshold = mPolicyThreshold.get();
            if (threshold == 0) {
                clearThrottleAndNotification();
                return;
            }

            // have we spoken with an ntp server yet?
            // this is controversial, but we'd rather err towards not throttling
            if (!mTime.hasCache()) {
                Slog.w(TAG, "missing trusted time, skipping throttle check");
                return;
            }

            // check if we need to throttle
            if (currentTotal > threshold) {
                if (mThrottleIndex.get() != 1) {
                    mThrottleIndex.set(1);
                    if (DBG) Slog.d(TAG, "Threshold " + threshold + " exceeded!");
                    try {
                        mNMService.setInterfaceThrottle(mIface,
                                mPolicyThrottleValue.get(), mPolicyThrottleValue.get());
                    } catch (Exception e) {
                        Slog.e(TAG, "error setting Throttle: " + e);
                    }

                    mNotificationManager.cancel(R.drawable.stat_sys_throttled);

                    postNotification(R.string.throttled_notification_title,
                            R.string.throttled_notification_message,
                            R.drawable.stat_sys_throttled,
                            Notification.FLAG_ONGOING_EVENT);

                    Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION);
                    broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL,
                            mPolicyThrottleValue.get());
                    mContext.sendStickyBroadcast(broadcast);

                } // else already up!
            } else {
                clearThrottleAndNotification();
                if ((mPolicyNotificationsAllowedMask & NOTIFICATION_WARNING) != 0) {
                    // check if we should warn about throttle
                    // pretend we only have 1/2 the time remaining that we actually do
                    // if our burn rate in the period so far would have us exceed the limit
                    // in that 1/2 window, warn the user.
                    // this gets more generous in the early to middle period and converges back
                    // to the limit as we move toward the period end.

                    // adding another factor - it must be greater than the total cap/4
                    // else we may get false alarms very early in the period..  in the first
                    // tenth of a percent of the period if we used more than a tenth of a percent
                    // of the cap we'd get a warning and that's not desired.
                    long start = mRecorder.getPeriodStart();
                    long end = mRecorder.getPeriodEnd();
                    long periodLength = end - start;
                    long now = System.currentTimeMillis();
                    long timeUsed = now - start;
                    long warningThreshold = 2*threshold*timeUsed/(timeUsed+periodLength);
                    if ((currentTotal > warningThreshold) && (currentTotal > threshold/4)) {
                        if (mWarningNotificationSent == false) {
                            mWarningNotificationSent = true;
                            mNotificationManager.cancel(R.drawable.stat_sys_throttled);
                            postNotification(R.string.throttle_warning_notification_title,
                                    R.string.throttle_warning_notification_message,
                                    R.drawable.stat_sys_throttled,
                                    0);
                        }
                    } else {
                        if (mWarningNotificationSent == true) {
                            mNotificationManager.cancel(R.drawable.stat_sys_throttled);
                            mWarningNotificationSent =false;
                        }
                    }
                }
            }
        }

        private void postNotification(int titleInt, int messageInt, int icon, int flags) {
            Intent intent = new Intent();
            // TODO - fix up intent
            intent.setClassName("com.android.phone", "com.android.phone.DataUsage");
            intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);

            Resources r = Resources.getSystem();
            CharSequence title = r.getText(titleInt);
            CharSequence message = r.getText(messageInt);
            if (mThrottlingNotification == null) {
                mThrottlingNotification = new Notification();
                mThrottlingNotification.when = 0;
                // TODO -  fixup icon
                mThrottlingNotification.icon = icon;
                mThrottlingNotification.defaults &= ~Notification.DEFAULT_SOUND;
            }
            mThrottlingNotification.flags = flags;
            mThrottlingNotification.tickerText = title;
            mThrottlingNotification.setLatestEventInfo(mContext, title, message, pi);

            mNotificationManager.notify(mThrottlingNotification.icon, mThrottlingNotification);
        }


        private void clearThrottleAndNotification() {
            if (mThrottleIndex.get() != THROTTLE_INDEX_UNTHROTTLED) {
                mThrottleIndex.set(THROTTLE_INDEX_UNTHROTTLED);
                try {
                    mNMService.setInterfaceThrottle(mIface, -1, -1);
                } catch (Exception e) {
                    Slog.e(TAG, "error clearing Throttle: " + e);
                }
                Intent broadcast = new Intent(ThrottleManager.THROTTLE_ACTION);
                broadcast.putExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1);
                mContext.sendStickyBroadcast(broadcast);
                mNotificationManager.cancel(R.drawable.stat_sys_throttled);
                mWarningNotificationSent = false;
            }
        }

        private Calendar calculatePeriodEnd(long now) {
            Calendar end = GregorianCalendar.getInstance();
            end.setTimeInMillis(now);
            int day = end.get(Calendar.DAY_OF_MONTH);
            end.set(Calendar.DAY_OF_MONTH, mPolicyResetDay);
            end.set(Calendar.HOUR_OF_DAY, 0);
            end.set(Calendar.MINUTE, 0);
            end.set(Calendar.SECOND, 0);
            end.set(Calendar.MILLISECOND, 0);
            if (day >= mPolicyResetDay) {
                int month = end.get(Calendar.MONTH);
                if (month == Calendar.DECEMBER) {
                    end.set(Calendar.YEAR, end.get(Calendar.YEAR) + 1);
                    month = Calendar.JANUARY - 1;
                }
                end.set(Calendar.MONTH, month + 1);
            }

            // TODO - remove!
            if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) {
                end = GregorianCalendar.getInstance();
                end.setTimeInMillis(now);
                end.add(Calendar.SECOND, TESTING_RESET_PERIOD_SEC);
            }
            return end;
        }
        private Calendar calculatePeriodStart(Calendar end) {
            Calendar start = (Calendar)end.clone();
            int month = end.get(Calendar.MONTH);
            if (end.get(Calendar.MONTH) == Calendar.JANUARY) {
                month = Calendar.DECEMBER + 1;
                start.set(Calendar.YEAR, start.get(Calendar.YEAR) - 1);
            }
            start.set(Calendar.MONTH, month - 1);

            // TODO - remove!!
            if (SystemProperties.get(TESTING_ENABLED_PROPERTY).equals("true")) {
                start = (Calendar)end.clone();
                start.add(Calendar.SECOND, -TESTING_RESET_PERIOD_SEC);
            }
            return start;
        }

        private void onResetAlarm() {
            if (VDBG || (mPolicyThreshold.get() != 0)) {
                Slog.d(TAG, "onResetAlarm - last period had " + mRecorder.getPeriodRx(0) +
                        " bytes read and " + mRecorder.getPeriodTx(0) + " written");
            }

            // when trusted cache outdated, try refreshing
            if (mTime.getCacheAge() > mMaxNtpCacheAge) {
                mTime.forceRefresh();
            }

            // as long as we have a trusted time cache, we always reset alarms,
            // even if the refresh above failed.
            if (mTime.hasCache()) {
                final long now = mTime.currentTimeMillis();
                Calendar end = calculatePeriodEnd(now);
                Calendar start = calculatePeriodStart(end);

                if (mRecorder.setNextPeriod(start, end)) {
                    onPollAlarm();
                }

                mAlarmManager.cancel(mPendingResetIntent);
                long offset = end.getTimeInMillis() - now;
                // use Elapsed realtime so clock changes don't fool us.
                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
                        SystemClock.elapsedRealtime() + offset,
                        mPendingResetIntent);
            } else {
                if (VDBG) Slog.d(TAG, "no trusted time, not resetting period");
            }
        }
    }

    // records bytecount data for a given time and accumulates it into larger time windows
    // for logging and other purposes
    //
    // since time can be changed (user or network action) we will have to track the time of the
    // last recording and deal with it.
    private static class DataRecorder {
        long[] mPeriodRxData;
        long[] mPeriodTxData;
        int mCurrentPeriod;
        int mPeriodCount;

        Calendar mPeriodStart;
        Calendar mPeriodEnd;

        ThrottleService mParent;
        Context mContext;
        String mImsi = null;

        TelephonyManager mTelephonyManager;

        DataRecorder(Context context, ThrottleService parent) {
            mContext = context;
            mParent = parent;

            mTelephonyManager = (TelephonyManager)mContext.getSystemService(
                    Context.TELEPHONY_SERVICE);

            synchronized (mParent) {
                mPeriodCount = 6;
                mPeriodRxData = new long[mPeriodCount];
                mPeriodTxData = new long[mPeriodCount];

                mPeriodStart = Calendar.getInstance();
                mPeriodEnd = Calendar.getInstance();

                retrieve();
            }
        }

        boolean setNextPeriod(Calendar start, Calendar end) {
            // TODO - how would we deal with a dual-IMSI device?
            checkForSubscriberId();
            boolean startNewPeriod = true;

            if (start.equals(mPeriodStart) && end.equals(mPeriodEnd)) {
                // same endpoints - keep collecting
                if (VDBG) {
                    Slog.d(TAG, "same period (" + start.getTimeInMillis() + "," +
                            end.getTimeInMillis() +") - ammending data");
                }
                startNewPeriod = false;
            } else {
                if (VDBG) {
                    if(start.equals(mPeriodEnd) || start.after(mPeriodEnd)) {
                        Slog.d(TAG, "next period (" + start.getTimeInMillis() + "," +
                                end.getTimeInMillis() + ") - old end was " +
                                mPeriodEnd.getTimeInMillis() + ", following");
                    } else {
                        Slog.d(TAG, "new period (" + start.getTimeInMillis() + "," +
                                end.getTimeInMillis() + ") replacing old (" +
                                mPeriodStart.getTimeInMillis() + "," +
                                mPeriodEnd.getTimeInMillis() + ")");
                    }
                }
                synchronized (mParent) {
                    ++mCurrentPeriod;
                    if (mCurrentPeriod >= mPeriodCount) mCurrentPeriod = 0;
                    mPeriodRxData[mCurrentPeriod] = 0;
                    mPeriodTxData[mCurrentPeriod] = 0;
                }
            }
            setPeriodStart(start);
            setPeriodEnd(end);
            record();
            return startNewPeriod;
        }

        public long getPeriodEnd() {
            synchronized (mParent) {
                return mPeriodEnd.getTimeInMillis();
            }
        }

        private void setPeriodEnd(Calendar end) {
            synchronized (mParent) {
                mPeriodEnd = end;
            }
        }

        public long getPeriodStart() {
            synchronized (mParent) {
                return mPeriodStart.getTimeInMillis();
            }
        }

        private void setPeriodStart(Calendar start) {
            synchronized (mParent) {
                mPeriodStart = start;
            }
        }

        public int getPeriodCount() {
            synchronized (mParent) {
                return mPeriodCount;
            }
        }

        private void zeroData(int field) {
            synchronized (mParent) {
                for(int period = 0; period<mPeriodCount; period++) {
                    mPeriodRxData[period] = 0;
                    mPeriodTxData[period] = 0;
                }
                mCurrentPeriod = 0;
            }

        }

        // if time moves backward accumulate all read/write that's lost into the now
        // otherwise time moved forward.
        void addData(long bytesRead, long bytesWritten) {
            checkForSubscriberId();

            synchronized (mParent) {
                mPeriodRxData[mCurrentPeriod] += bytesRead;
                mPeriodTxData[mCurrentPeriod] += bytesWritten;
            }
            record();
        }

        private File getDataFile() {
            File dataDir = Environment.getDataDirectory();
            File throttleDir = new File(dataDir, "system/throttle");
            throttleDir.mkdirs();
            String mImsi = mTelephonyManager.getSubscriberId();
            File dataFile;
            if (mImsi == null) {
                dataFile = useMRUFile(throttleDir);
                if (VDBG) Slog.v(TAG, "imsi not available yet, using " + dataFile);
            } else {
                String imsiHash = Integer.toString(mImsi.hashCode());
                dataFile = new File(throttleDir, imsiHash);
            }
            // touch the file so it's not LRU
            dataFile.setLastModified(System.currentTimeMillis());
            checkAndDeleteLRUDataFile(throttleDir);
            return dataFile;
        }

        // TODO - get broadcast (TelephonyIntents.ACTION_SIM_STATE_CHANGED) instead of polling
        private void checkForSubscriberId() {
            if (mImsi != null) return;

            mImsi = mTelephonyManager.getSubscriberId();
            if (mImsi == null) return;

            if (VDBG) Slog.d(TAG, "finally have imsi - retreiving data");
            retrieve();
        }

        private final static int MAX_SIMS_SUPPORTED = 3;

        private void checkAndDeleteLRUDataFile(File dir) {
            File[] files = dir.listFiles();

            if (files == null || files.length <= MAX_SIMS_SUPPORTED) return;
            if (DBG) Slog.d(TAG, "Too many data files");
            do {
                File oldest = null;
                for (File f : files) {
                    if ((oldest == null) || (oldest.lastModified() > f.lastModified())) {
                        oldest = f;
                    }
                }
                if (oldest == null) return;
                if (DBG) Slog.d(TAG, " deleting " + oldest);
                oldest.delete();
                files = dir.listFiles();
            } while (files.length > MAX_SIMS_SUPPORTED);
        }

        private File useMRUFile(File dir) {
            File newest = null;
            File[] files = dir.listFiles();

            if (files != null) {
                for (File f : files) {
                    if ((newest == null) || (newest.lastModified() < f.lastModified())) {
                        newest = f;
                    }
                }
            }
            if (newest == null) {
                newest = new File(dir, "temp");
            }
            return newest;
        }


        private static final int DATA_FILE_VERSION = 1;

        private void record() {
            // 1 int version
            // 1 int mPeriodCount
            // 13*6 long[PERIOD_COUNT] mPeriodRxData
            // 13*6 long[PERIOD_COUNT] mPeriodTxData
            // 1  int mCurrentPeriod
            // 13 long periodStartMS
            // 13 long periodEndMS
            // 200 chars max
            StringBuilder builder = new StringBuilder();
            builder.append(DATA_FILE_VERSION);
            builder.append(":");
            builder.append(mPeriodCount);
            builder.append(":");
            for(int i = 0; i < mPeriodCount; i++) {
                builder.append(mPeriodRxData[i]);
                builder.append(":");
            }
            for(int i = 0; i < mPeriodCount; i++) {
                builder.append(mPeriodTxData[i]);
                builder.append(":");
            }
            builder.append(mCurrentPeriod);
            builder.append(":");
            builder.append(mPeriodStart.getTimeInMillis());
            builder.append(":");
            builder.append(mPeriodEnd.getTimeInMillis());

            BufferedWriter out = null;
            try {
                out = new BufferedWriter(new FileWriter(getDataFile()), 256);
                out.write(builder.toString());
            } catch (IOException e) {
                Slog.e(TAG, "Error writing data file");
                return;
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (Exception e) {}
                }
            }
        }

        private void retrieve() {
            // clean out any old data first.  If we fail to read we don't want old stuff
            zeroData(0);

            File f = getDataFile();
            byte[] buffer;
            FileInputStream s = null;
            try {
                buffer = new byte[(int)f.length()];
                s = new FileInputStream(f);
                s.read(buffer);
            } catch (IOException e) {
                Slog.e(TAG, "Error reading data file");
                return;
            } finally {
                if (s != null) {
                    try {
                        s.close();
                    } catch (Exception e) {}
                }
            }
            String data = new String(buffer);
            if (data == null || data.length() == 0) {
                if (DBG) Slog.d(TAG, "data file empty");
                return;
            }
            String[] parsed = data.split(":");
            int parsedUsed = 0;
            if (parsed.length < 6) {
                Slog.e(TAG, "reading data file with insufficient length - ignoring");
                return;
            }

            int periodCount;
            long[] periodRxData;
            long[] periodTxData;
            int currentPeriod;
            Calendar periodStart;
            Calendar periodEnd;
            try {
                if (Integer.parseInt(parsed[parsedUsed++]) != DATA_FILE_VERSION) {
                    Slog.e(TAG, "reading data file with bad version - ignoring");
                    return;
                }

                periodCount = Integer.parseInt(parsed[parsedUsed++]);
                if (parsed.length != 5 + (2 * periodCount)) {
                    Slog.e(TAG, "reading data file with bad length (" + parsed.length +
                            " != " + (5 + (2 * periodCount)) + ") - ignoring");
                    return;
                }
                periodRxData = new long[periodCount];
                for (int i = 0; i < periodCount; i++) {
                    periodRxData[i] = Long.parseLong(parsed[parsedUsed++]);
                }
                periodTxData = new long[periodCount];
                for (int i = 0; i < periodCount; i++) {
                    periodTxData[i] = Long.parseLong(parsed[parsedUsed++]);
                }

                currentPeriod = Integer.parseInt(parsed[parsedUsed++]);

                periodStart = new GregorianCalendar();
                periodStart.setTimeInMillis(Long.parseLong(parsed[parsedUsed++]));
                periodEnd = new GregorianCalendar();
                periodEnd.setTimeInMillis(Long.parseLong(parsed[parsedUsed++]));
            } catch (Exception e) {
                Slog.e(TAG, "Error parsing data file - ignoring");
                return;
            }
            synchronized (mParent) {
                mPeriodCount = periodCount;
                mPeriodRxData = periodRxData;
                mPeriodTxData = periodTxData;
                mCurrentPeriod = currentPeriod;
                mPeriodStart = periodStart;
                mPeriodEnd = periodEnd;
            }
        }

        long getPeriodRx(int which) {
            synchronized (mParent) {
                if (which > mPeriodCount) return 0;
                which = mCurrentPeriod - which;
                if (which < 0) which += mPeriodCount;
                return mPeriodRxData[which];
            }
        }
        long getPeriodTx(int which) {
            synchronized (mParent) {
                if (which > mPeriodCount) return 0;
                which = mCurrentPeriod - which;
                if (which < 0) which += mPeriodCount;
                return mPeriodTxData[which];
            }
        }
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump ThrottleService " +
                    "from from pid=" + Binder.getCallingPid() + ", uid=" +
                    Binder.getCallingUid());
            return;
        }
        pw.println();

        pw.println("The threshold is " + mPolicyThreshold.get() +
                ", after which you experince throttling to " +
                mPolicyThrottleValue.get() + "kbps");
        pw.println("Current period is " +
                (mRecorder.getPeriodEnd() - mRecorder.getPeriodStart())/1000 + " seconds long " +
                "and ends in " + (getResetTime(mIface) - System.currentTimeMillis()) / 1000 +
                " seconds.");
        pw.println("Polling every " + mPolicyPollPeriodSec + " seconds");
        pw.println("Current Throttle Index is " + mThrottleIndex.get());
        pw.println("mMaxNtpCacheAge=" + mMaxNtpCacheAge);

        for (int i = 0; i < mRecorder.getPeriodCount(); i++) {
            pw.println(" Period[" + i + "] - read:" + mRecorder.getPeriodRx(i) + ", written:" +
                    mRecorder.getPeriodTx(i));
        }
    }
}
