Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.phone;
     18 
     19 import com.android.phone.R;
     20 
     21 import android.content.BroadcastReceiver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.IntentFilter;
     25 import android.os.Bundle;
     26 import android.preference.Preference;
     27 import android.preference.PreferenceActivity;
     28 import android.preference.PreferenceScreen;
     29 import android.net.Uri;
     30 import android.net.ThrottleManager;
     31 import android.util.Log;
     32 
     33 import java.util.Calendar;
     34 import java.util.GregorianCalendar;
     35 import java.text.DateFormat;
     36 
     37 /**
     38  * Listener for broadcasts from ThrottleManager
     39  */
     40 public class DataUsageListener {
     41 
     42     private ThrottleManager mThrottleManager;
     43     private Preference mCurrentUsagePref = null;
     44     private Preference mTimeFramePref = null;
     45     private Preference mThrottleRatePref = null;
     46     private Preference mSummaryPref = null;
     47     private PreferenceScreen mPrefScreen = null;
     48     private boolean mSummaryPrefEnabled = false;
     49 
     50     private final Context mContext;
     51     private IntentFilter mFilter;
     52     private BroadcastReceiver mReceiver;
     53 
     54     private int mPolicyThrottleValue;  //in kbps
     55     private long mPolicyThreshold;
     56     private int mCurrentThrottleRate;
     57     private long mDataUsed;
     58     private Calendar mStart;
     59     private Calendar mEnd;
     60 
     61     public DataUsageListener(Context context, Preference summary, PreferenceScreen prefScreen) {
     62         mContext = context;
     63         mSummaryPref = summary;
     64         mPrefScreen = prefScreen;
     65         mSummaryPrefEnabled = true;
     66         initialize();
     67     }
     68 
     69     public DataUsageListener(Context context, Preference currentUsage,
     70             Preference timeFrame, Preference throttleRate) {
     71         mContext = context;
     72         mCurrentUsagePref = currentUsage;
     73         mTimeFramePref = timeFrame;
     74         mThrottleRatePref = throttleRate;
     75         initialize();
     76     }
     77 
     78     private void initialize() {
     79 
     80         mThrottleManager = (ThrottleManager) mContext.getSystemService(Context.THROTTLE_SERVICE);
     81 
     82         mStart = GregorianCalendar.getInstance();
     83         mEnd = GregorianCalendar.getInstance();
     84 
     85         mFilter = new IntentFilter();
     86         mFilter.addAction(ThrottleManager.THROTTLE_POLL_ACTION);
     87         mFilter.addAction(ThrottleManager.THROTTLE_ACTION);
     88         mFilter.addAction(ThrottleManager.POLICY_CHANGED_ACTION);
     89 
     90         mReceiver = new BroadcastReceiver() {
     91             @Override
     92             public void onReceive(Context context, Intent intent) {
     93                 String action = intent.getAction();
     94                 if (ThrottleManager.THROTTLE_POLL_ACTION.equals(action)) {
     95                     updateUsageStats(intent.getLongExtra(ThrottleManager.EXTRA_CYCLE_READ, 0),
     96                         intent.getLongExtra(ThrottleManager.EXTRA_CYCLE_WRITE, 0),
     97                         intent.getLongExtra(ThrottleManager.EXTRA_CYCLE_START, 0),
     98                         intent.getLongExtra(ThrottleManager.EXTRA_CYCLE_END, 0));
     99                 } else if (ThrottleManager.POLICY_CHANGED_ACTION.equals(action)) {
    100                     updatePolicy();
    101                 } else if (ThrottleManager.THROTTLE_ACTION.equals(action)) {
    102                     updateThrottleRate(intent.getIntExtra(ThrottleManager.EXTRA_THROTTLE_LEVEL, -1));
    103                 }
    104             }
    105         };
    106     }
    107 
    108     void resume() {
    109         mContext.registerReceiver(mReceiver, mFilter);
    110         updatePolicy();
    111     }
    112 
    113     void pause() {
    114         mContext.unregisterReceiver(mReceiver);
    115     }
    116 
    117     private void updatePolicy() {
    118         /* Fetch values for default interface */
    119         mPolicyThrottleValue = mThrottleManager.getCliffLevel(null, 1);
    120         mPolicyThreshold = mThrottleManager.getCliffThreshold(null, 1);
    121 
    122         if (mSummaryPref != null) { /* Settings preference */
    123             /**
    124              * Remove data usage preference in settings
    125              * if policy change disables throttling
    126              */
    127             if (mPolicyThreshold == 0) {
    128                 if (mSummaryPrefEnabled) {
    129                     mPrefScreen.removePreference(mSummaryPref);
    130                     mSummaryPrefEnabled = false;
    131                 }
    132             } else {
    133                 if (!mSummaryPrefEnabled) {
    134                     mSummaryPrefEnabled = true;
    135                     mPrefScreen.addPreference(mSummaryPref);
    136                 }
    137             }
    138         }
    139         updateUI();
    140     }
    141 
    142     private void updateThrottleRate(int throttleRate) {
    143         mCurrentThrottleRate = throttleRate;
    144         updateUI();
    145     }
    146 
    147     private void updateUsageStats(long readByteCount, long writeByteCount,
    148             long startTime, long endTime) {
    149         mDataUsed = readByteCount + writeByteCount;
    150         mStart.setTimeInMillis(startTime);
    151         mEnd.setTimeInMillis(endTime);
    152         updateUI();
    153     }
    154 
    155     private void updateUI() {
    156         if (mPolicyThreshold == 0)
    157             return;
    158         int dataUsedPercent = (int) ((mDataUsed * 100) / mPolicyThreshold);
    159 
    160         long cycleTime = mEnd.getTimeInMillis() - mStart.getTimeInMillis();
    161         long currentTime = GregorianCalendar.getInstance().getTimeInMillis()
    162                             - mStart.getTimeInMillis();
    163 
    164         int cycleThroughPercent = (cycleTime == 0) ? 0 : (int) ((currentTime * 100) / cycleTime);
    165 
    166         Calendar cal = Calendar.getInstance();
    167         cal.setTimeInMillis(cycleTime - currentTime);
    168         int daysLeft = cal.get(Calendar.DAY_OF_YEAR);
    169         //cal.get() returns 365 for less than a day
    170         if (daysLeft >= 365) daysLeft = 0;
    171 
    172         if (mCurrentUsagePref != null) {
    173             /* Update the UI based on whether we are in a throttled state */
    174             if (mCurrentThrottleRate > 0) {
    175                 mCurrentUsagePref.setSummary(mContext.getString(
    176                         R.string.throttle_data_rate_reduced_subtext,
    177                         toReadable(mPolicyThreshold),
    178                         mCurrentThrottleRate));
    179             } else {
    180                 mCurrentUsagePref.setSummary(mContext.getString(
    181                         R.string.throttle_data_usage_subtext,
    182                         toReadable(mDataUsed), dataUsedPercent, toReadable(mPolicyThreshold)));
    183             }
    184         }
    185         if (mTimeFramePref != null) {
    186             mTimeFramePref.setSummary(mContext.getString(R.string.throttle_time_frame_subtext,
    187                         cycleThroughPercent, daysLeft,
    188                         DateFormat.getDateInstance(DateFormat.SHORT).format(mEnd.getTime())));
    189         }
    190         if (mThrottleRatePref != null) {
    191             mThrottleRatePref.setSummary(mContext.getString(R.string.throttle_rate_subtext,
    192                     mPolicyThrottleValue));
    193         }
    194         if (mSummaryPref != null && mSummaryPrefEnabled) {
    195 
    196             /* Update the UI based on whether we are in a throttled state */
    197             if (mCurrentThrottleRate > 0) {
    198                 mSummaryPref.setSummary(mContext.getString(
    199                         R.string.throttle_data_rate_reduced_subtext,
    200                         toReadable(mPolicyThreshold),
    201                         mCurrentThrottleRate));
    202             } else {
    203                 mSummaryPref.setSummary(mContext.getString(R.string.throttle_status_subtext,
    204                             toReadable(mDataUsed),
    205                             dataUsedPercent,
    206                             toReadable(mPolicyThreshold),
    207                             daysLeft,
    208                             DateFormat.getDateInstance(DateFormat.SHORT).format(mEnd.getTime())));
    209             }
    210         }
    211     }
    212 
    213     private String toReadable (long data) {
    214         long KB = 1024;
    215         long MB = 1024 * KB;
    216         long GB = 1024 * MB;
    217         long TB = 1024 * GB;
    218         String ret;
    219 
    220         if (data < KB) {
    221             ret = data + " bytes";
    222         } else if (data < MB) {
    223             ret = (data / KB) + " KB";
    224         } else if (data < GB) {
    225             ret = (data / MB) + " MB";
    226         } else if (data < TB) {
    227             ret = (data / GB) + " GB";
    228         } else {
    229             ret = (data / TB) + " TB";
    230         }
    231         return ret;
    232     }
    233 }
    234