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