diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/settings/DataUsageSummary.java | 9 | ||||
-rw-r--r-- | src/com/android/settings/DevelopmentSettings.java | 19 | ||||
-rw-r--r-- | src/com/android/settings/RadioInfo.java | 7 | ||||
-rw-r--r-- | src/com/android/settings/Utils.java | 21 | ||||
-rw-r--r-- | src/com/android/settings/fuelgauge/BatteryHistoryChart.java | 671 | ||||
-rw-r--r-- | src/com/android/settings/fuelgauge/PowerUsageSummary.java | 1 | ||||
-rw-r--r-- | src/com/android/settings/notification/NotificationStation.java | 4 | ||||
-rw-r--r-- | src/com/android/settings/wifi/AccessPoint.java | 68 | ||||
-rw-r--r-- | src/com/android/settings/wifi/WifiConfigController.java | 62 | ||||
-rw-r--r-- | src/com/android/settings/wifi/WifiSettings.java | 5 |
10 files changed, 669 insertions, 198 deletions
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java index 9f680231f..86a73c28f 100644 --- a/src/com/android/settings/DataUsageSummary.java +++ b/src/com/android/settings/DataUsageSummary.java @@ -192,7 +192,8 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable private INetworkManagementService mNetworkService; private INetworkStatsService mStatsService; private NetworkPolicyManager mPolicyManager; - private ConnectivityManager mConnService; + private TelephonyManager mTelephonyManager; + private INetworkStatsSession mStatsSession; @@ -274,7 +275,7 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable mStatsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); mPolicyManager = NetworkPolicyManager.from(context); - mConnService = ConnectivityManager.from(context); + mTelephonyManager = TelephonyManager.from(context); mPrefs = getActivity().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE); @@ -872,13 +873,13 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable // TODO: deprecate and remove this once enabled flag is on policy return mMobileDataEnabled; } else { - return mConnService.getMobileDataEnabled(); + return mTelephonyManager.getDataEnabled(); } } private void setMobileDataEnabled(boolean enabled) { if (LOGD) Log.d(TAG, "setMobileDataEnabled()"); - mConnService.setMobileDataEnabled(enabled); + mTelephonyManager.setDataEnabled(enabled); mMobileDataEnabled = enabled; updatePolicy(false); } diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java index cc7a116f3..1cd08f399 100644 --- a/src/com/android/settings/DevelopmentSettings.java +++ b/src/com/android/settings/DevelopmentSettings.java @@ -34,6 +34,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.hardware.usb.IUsbManager; +import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.BatteryManager; import android.os.Build; @@ -138,6 +139,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category"; private static final String DEBUG_APPLICATIONS_CATEGORY_KEY = "debug_applications_category"; private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification"; + private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging"; private static final String OPENGL_TRACES_KEY = "enable_opengl_traces"; @@ -163,6 +165,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private IBackupManager mBackupManager; private DevicePolicyManager mDpm; private UserManager mUm; + private WifiManager mWifiManager; private SwitchBar mSwitchBar; private Switch mEnabledSwitch; @@ -185,6 +188,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private CheckBoxPreference mWaitForDebugger; private CheckBoxPreference mVerifyAppsOverUsb; private CheckBoxPreference mWifiDisplayCertification; + private CheckBoxPreference mWifiVerboseLogging; private CheckBoxPreference mStrictMode; private CheckBoxPreference mPointerLocation; @@ -244,6 +248,8 @@ public class DevelopmentSettings extends SettingsPreferenceFragment mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE); mUm = (UserManager) getSystemService(Context.USER_SERVICE); + mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); + if (android.os.Process.myUserHandle().getIdentifier() != UserHandle.USER_OWNER || mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) { mUnavailable = true; @@ -313,6 +319,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment mForceRtlLayout = findAndInitCheckboxPref(FORCE_RTL_LAYOUT_KEY); mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY); mWifiDisplayCertification = findAndInitCheckboxPref(WIFI_DISPLAY_CERTIFICATION_KEY); + mWifiVerboseLogging = findAndInitCheckboxPref(WIFI_VERBOSE_LOGGING_KEY); mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY); mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY); mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY); @@ -517,6 +524,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment updateBugreportOptions(); updateForceRtlOptions(); updateWifiDisplayCertificationOptions(); + updateWifiVerboseLoggingOptions(); updateSimulateColorSpace(); updateUseNuplayerOptions(); } @@ -1023,6 +1031,15 @@ public class DevelopmentSettings extends SettingsPreferenceFragment mWifiDisplayCertification.isChecked() ? 1 : 0); } + private void updateWifiVerboseLoggingOptions() { + boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0; + updateCheckBox(mWifiVerboseLogging, enabled); + } + + private void writeWifiVerboseLoggingOptions() { + mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0); + } + private void updateLowPowerModeOptions() { updateCheckBox(mLowPowerMode, Settings.Global.getInt(getActivity().getContentResolver(), Settings.Global.LOW_POWER_MODE, 0) != 0); @@ -1339,6 +1356,8 @@ public class DevelopmentSettings extends SettingsPreferenceFragment writeForceRtlOptions(); } else if (preference == mWifiDisplayCertification) { writeWifiDisplayCertificationOptions(); + } else if (preference == mWifiVerboseLogging) { + writeWifiVerboseLoggingOptions(); } else if (preference == mUseNuplayer) { writeUseNuplayerOptions(); } else { diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java index 4c861440d..b0a4a537a 100644 --- a/src/com/android/settings/RadioInfo.java +++ b/src/com/android/settings/RadioInfo.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; -import android.net.ConnectivityManager; import android.net.TrafficStats; import android.net.Uri; import android.os.AsyncResult; @@ -917,15 +916,13 @@ public class RadioInfo extends Activity { private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { - ConnectivityManager cm = - (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); int state = mTelephonyManager.getDataState(); switch (state) { case TelephonyManager.DATA_CONNECTED: - cm.setMobileDataEnabled(false); + phone.setDataEnabled(false); break; case TelephonyManager.DATA_DISCONNECTED: - cm.setMobileDataEnabled(true); + phone.setDataEnabled(true); break; default: // do nothing diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 36e19046b..1b640642f 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -312,18 +312,17 @@ public class Utils { BatteryManager.BATTERY_STATUS_UNKNOWN); String statusString; if (status == BatteryManager.BATTERY_STATUS_CHARGING) { - statusString = res.getString(R.string.battery_info_status_charging); - if (plugType > 0) { - int resId; - if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { - resId = R.string.battery_info_status_charging_ac; - } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { - resId = R.string.battery_info_status_charging_usb; - } else { - resId = R.string.battery_info_status_charging_wireless; - } - statusString = statusString + " " + res.getString(resId); + int resId; + if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { + resId = R.string.battery_info_status_charging_ac; + } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { + resId = R.string.battery_info_status_charging_usb; + } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { + resId = R.string.battery_info_status_charging_wireless; + } else { + resId = R.string.battery_info_status_charging; } + statusString = res.getString(resId); } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { statusString = res.getString(R.string.battery_info_status_discharging); } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java index da6729c3a..f718b4243 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -17,8 +17,13 @@ package com.android.settings.fuelgauge; import android.content.Intent; +import android.graphics.DashPathEffect; import android.os.BatteryManager; +import android.provider.Settings; +import android.text.format.DateFormat; import android.text.format.Formatter; +import android.util.Log; +import android.util.TimeUtils; import com.android.settings.R; import android.content.Context; @@ -36,8 +41,15 @@ import android.text.TextPaint; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; +import libcore.icu.LocaleData; + +import java.util.ArrayList; +import java.util.Calendar; public class BatteryHistoryChart extends View { + static final boolean DEBUG = false; + static final String TAG = "BatteryHistoryChart"; + static final int CHART_DATA_X_MASK = 0x0000ffff; static final int CHART_DATA_BIN_MASK = 0xffff0000; static final int CHART_DATA_BIN_SHIFT = 16; @@ -116,28 +128,35 @@ public class BatteryHistoryChart extends View { final Paint mBatteryGoodPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + final Paint mTimeRemainPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mChargingPaint = new Paint(); final Paint mScreenOnPaint = new Paint(); final Paint mGpsOnPaint = new Paint(); final Paint mWifiRunningPaint = new Paint(); final Paint mCpuRunningPaint = new Paint(); + final Paint mDateLinePaint = new Paint(); final ChartData mPhoneSignalChart = new ChartData(); final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); final TextPaint mHeaderTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + final Paint mDebugRectPaint = new Paint(); final Path mBatLevelPath = new Path(); final Path mBatGoodPath = new Path(); final Path mBatWarnPath = new Path(); final Path mBatCriticalPath = new Path(); + final Path mTimeRemainPath = new Path(); final Path mChargingPath = new Path(); final Path mScreenOnPath = new Path(); final Path mGpsOnPath = new Path(); final Path mWifiRunningPath = new Path(); final Path mCpuRunningPath = new Path(); + final Path mDateLinePath = new Path(); BatteryStats mStats; Intent mBatteryBroadcast; long mStatsPeriod; + String mMaxPercentLabelString; + String mMinPercentLabelString; String mDurationString; String mChargeLabelString; String mChargeDurationString; @@ -153,6 +172,8 @@ public class BatteryHistoryChart extends View { int mTextDescent; int mHeaderTextAscent; int mHeaderTextDescent; + int mMaxPercentLabelStringWidth; + int mMinPercentLabelStringWidth; int mDurationStringWidth; int mChargeLabelStringWidth; int mChargeDurationStringWidth; @@ -160,6 +181,9 @@ public class BatteryHistoryChart extends View { boolean mLargeMode; + int mLastWidth = -1; + int mLastHeight = -1; + int mLineWidth; int mThinLineWidth; int mChargingOffset; @@ -171,19 +195,29 @@ public class BatteryHistoryChart extends View { int mLevelOffset; int mLevelTop; int mLevelBottom; + int mLevelLeft; + int mLevelRight; static final int PHONE_SIGNAL_X_MASK = CHART_DATA_X_MASK; static final int PHONE_SIGNAL_BIN_MASK = CHART_DATA_BIN_MASK; static final int PHONE_SIGNAL_BIN_SHIFT = CHART_DATA_BIN_SHIFT; int mNumHist; long mHistStart; + long mHistDataEnd; long mHistEnd; + long mStartWallTime; + long mEndDataWallTime; + long mEndWallTime; + boolean mDischarging; int mBatLow; int mBatHigh; boolean mHaveWifi; boolean mHaveGps; boolean mHavePhoneSignal; + final ArrayList<TimeLabel> mTimeLabels = new ArrayList<TimeLabel>(); + final ArrayList<DateLabel> mDateLabels = new ArrayList<DateLabel>(); + static class TextAttrs { ColorStateList textColor = null; int textSize = 15; @@ -273,10 +307,56 @@ public class BatteryHistoryChart extends View { } } + static class TimeLabel { + final int x; + final String label; + final int width; + + TimeLabel(Context context, TextPaint paint, int x, Calendar cal, boolean use24hr) { + this.x = x; + if (use24hr) { + label = context.getString(R.string.battery_stats_hour_24_label, + cal.get(Calendar.HOUR_OF_DAY)); + } else { + int hour = cal.get(Calendar.HOUR); + if (hour == 0) { + hour = 12; + } + if (cal.get(Calendar.AM_PM) == Calendar.AM) { + label = context.getString(R.string.battery_stats_hour_am_label, hour); + } else { + label = context.getString(R.string.battery_stats_hour_pm_label, hour); + } + } + width = (int)paint.measureText(label); + } + } + + static class DateLabel { + final int x; + final String label; + final int width; + + DateLabel(Context context, TextPaint paint, int x, Calendar cal, boolean dayFirst) { + this.x = x; + if (dayFirst) { + label = context.getString(R.string.battery_stats_date_day_first_label, + cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH)); + } else { + label = context.getString(R.string.battery_stats_date_month_first_label, + cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.MONTH)); + } + width = (int)paint.measureText(label); + } + } + public BatteryHistoryChart(Context context, AttributeSet attrs) { super(context, attrs); - mBatteryBackgroundPaint.setARGB(255, 128, 128, 128); + mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + 2, getResources().getDisplayMetrics()); + + mBatteryBackgroundPaint.setColor(0xff263238); mBatteryBackgroundPaint.setStyle(Paint.Style.FILL); mBatteryGoodPaint.setARGB(128, 0, 255, 0); mBatteryGoodPaint.setStyle(Paint.Style.STROKE); @@ -284,6 +364,8 @@ public class BatteryHistoryChart extends View { mBatteryWarnPaint.setStyle(Paint.Style.STROKE); mBatteryCriticalPaint.setARGB(192, 255, 0, 0); mBatteryCriticalPaint.setStyle(Paint.Style.STROKE); + mTimeRemainPaint.setColor(0xffA5B1B7); + mTimeRemainPaint.setStyle(Paint.Style.FILL); mChargingPaint.setARGB(255, 0, 128, 0); mChargingPaint.setStyle(Paint.Style.STROKE); mScreenOnPaint.setStyle(Paint.Style.STROKE); @@ -294,7 +376,9 @@ public class BatteryHistoryChart extends View { 0x00000000, 0xffa00000, 0xffa07000, 0xffa0a000, 0xff80a000, 0xff409000, 0xff008000 }); - + mDebugRectPaint.setARGB(255, 255, 0, 0); + mDebugRectPaint.setStyle(Paint.Style.STROKE); + TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.BatteryHistoryChart, 0, 0); @@ -355,12 +439,22 @@ public class BatteryHistoryChart extends View { mainTextAttrs.apply(context, mTextPaint); headTextAttrs.apply(context, mHeaderTextPaint); + mDateLinePaint.set(mTextPaint); + mDateLinePaint.setStyle(Paint.Style.STROKE); + int hairlineWidth = mThinLineWidth/2; + if (hairlineWidth < 1) { + hairlineWidth = 1; + } + mDateLinePaint.setStrokeWidth(hairlineWidth); + mDateLinePaint.setPathEffect(new DashPathEffect(new float[] { + mThinLineWidth * 2, mThinLineWidth * 2 }, 0)); + if (shadowcolor != 0) { mTextPaint.setShadowLayer(r, dx, dy, shadowcolor); mHeaderTextPaint.setShadowLayer(r, dx, dy, shadowcolor); } } - + void setStats(BatteryStats stats, Intent broadcast) { mStats = stats; mBatteryBroadcast = broadcast; @@ -376,32 +470,91 @@ public class BatteryHistoryChart extends View { mWifiRunningLabel = getContext().getString(R.string.battery_stats_wifi_running_label); mCpuRunningLabel = getContext().getString(R.string.battery_stats_wake_lock_label); mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label); - + + mMaxPercentLabelString = getContext().getResources().getString( + R.string.percentage, 100); + mMinPercentLabelString = getContext().getResources().getString( + R.string.percentage, 0); + + int batteryLevel = com.android.settings.Utils.getBatteryLevel(mBatteryBroadcast); + final int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS, + BatteryManager.BATTERY_STATUS_UNKNOWN); + long remainingTimeUs = 0; + mDischarging = true; + if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { + final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs); + if (drainTime > 0) { + remainingTimeUs = drainTime; + String timeString = Formatter.formatShortElapsedTime(getContext(), + drainTime / 1000); + mChargeLabelString = getContext().getResources().getString( + R.string.power_discharging_duration, batteryLevel, timeString); + } else { + mChargeLabelString = getContext().getResources().getString( + R.string.power_discharging, batteryLevel); + } + } else { + final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs); + final String statusLabel = com.android.settings.Utils.getBatteryStatus(getResources(), + mBatteryBroadcast); + if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { + mDischarging = false; + remainingTimeUs = chargeTime; + String timeString = Formatter.formatShortElapsedTime(getContext(), + chargeTime / 1000); + mChargeLabelString = getContext().getResources().getString( + R.string.power_charging_duration, batteryLevel, statusLabel, timeString); + } else { + mChargeLabelString = getContext().getResources().getString( + R.string.power_charging, batteryLevel, statusLabel); + } + } + mDrainString = ""; + mChargeDurationString = ""; + int pos = 0; int lastInteresting = 0; byte lastLevel = -1; mBatLow = 0; mBatHigh = 100; + mStartWallTime = 0; + mEndDataWallTime = 0; + mEndWallTime = 0; + mHistStart = 0; + mHistEnd = 0; + long lastWallTime = 0; + long lastRealtime = 0; int aggrStates = 0; boolean first = true; if (stats.startIteratingHistoryLocked()) { final HistoryItem rec = new HistoryItem(); while (stats.getNextHistoryLocked(rec)) { pos++; - if (rec.isDeltaData()) { - if (first) { - first = false; - mHistStart = rec.time; + if (first) { + first = false; + mHistStart = rec.time; + } + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME + || rec.cmd == HistoryItem.CMD_RESET) { + lastWallTime = rec.currentTime; + lastRealtime = rec.time; + if (mStartWallTime == 0) { + mStartWallTime = lastWallTime; } + } + if (rec.isDeltaData()) { if (rec.batteryLevel != lastLevel || pos == 1) { lastLevel = rec.batteryLevel; } lastInteresting = pos; - mHistEnd = rec.time; + mHistDataEnd = rec.time; aggrStates |= rec.states; } } } + mHistEnd = mHistDataEnd + (remainingTimeUs/1000); + mEndDataWallTime = lastWallTime + mHistDataEnd - lastRealtime; + mEndWallTime = mEndDataWallTime + (remainingTimeUs/1000); mNumHist = lastInteresting; mHaveGps = (aggrStates&HistoryItem.STATE_GPS_ON_FLAG) != 0; mHaveWifi = (aggrStates&HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0; @@ -414,41 +567,13 @@ public class BatteryHistoryChart extends View { //mDurationString = getContext().getString(R.string.battery_stats_on_battery, // durationString); mDurationString = Utils.formatElapsedTime(getContext(), mHistEnd - mHistStart, true); - int batteryLevel = com.android.settings.Utils.getBatteryLevel(mBatteryBroadcast); - final int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS, - BatteryManager.BATTERY_STATUS_UNKNOWN); - if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { - final long drainTime = mStats.computeBatteryTimeRemaining(elapsedRealtimeUs); - if (drainTime > 0) { - String timeString = Formatter.formatShortElapsedTime(getContext(), - drainTime / 1000); - mChargeLabelString = getContext().getResources().getString( - R.string.power_discharging_duration, batteryLevel, timeString); - } else { - mChargeLabelString = getContext().getResources().getString( - R.string.power_discharging, batteryLevel); - } - } else { - final long chargeTime = mStats.computeChargeTimeRemaining(elapsedRealtimeUs); - final String statusLabel = com.android.settings.Utils.getBatteryStatus(getResources(), - mBatteryBroadcast); - if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { - String timeString = Formatter.formatShortElapsedTime(getContext(), - chargeTime / 1000); - mChargeLabelString = getContext().getResources().getString( - R.string.power_charging_duration, batteryLevel, statusLabel, timeString); - } else { - mChargeLabelString = getContext().getResources().getString( - R.string.power_charging, batteryLevel, statusLabel); - } - } - mDrainString = ""; - mChargeDurationString = ""; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); + mMaxPercentLabelStringWidth = (int)mTextPaint.measureText(mMaxPercentLabelString); + mMinPercentLabelStringWidth = (int)mTextPaint.measureText(mMinPercentLabelString); mDurationStringWidth = (int)mTextPaint.measureText(mDurationString); mDrainStringWidth = (int)mHeaderTextPaint.measureText(mDrainString); mChargeLabelStringWidth = (int)mHeaderTextPaint.measureText(mChargeLabelString); @@ -493,15 +618,51 @@ public class BatteryHistoryChart extends View { mPhoneSignalChart.finish(w); } } - + + private boolean is24Hour() { + return DateFormat.is24HourFormat(getContext()); + } + + private boolean isDayFirst() { + String value = Settings.System.getString(mContext.getContentResolver(), + Settings.System.DATE_FORMAT); + if (value == null) { + LocaleData d = LocaleData.get(mContext.getResources().getConfiguration().locale); + value = d.shortDateFormat4; + } + return value.indexOf('M') > value.indexOf('d'); + } + + /* + private void buildTime() { + java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context); + final Calendar now = Calendar.getInstance(); + mDummyDate.setTimeZone(now.getTimeZone()); + // We use December 31st because it's unambiguous when demonstrating the date format. + // We use 13:00 so we can demonstrate the 12/24 hour options. + mDummyDate.set(now.get(Calendar.YEAR), 11, 31, 13, 0, 0); + Date dummyDate = mDummyDate.getTime(); + mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime())); + mTimeZone.setSummary(getTimeZoneText(now.getTimeZone(), true)); + mDatePref.setSummary(shortDateFormat.format(now.getTime())); + mDateFormat.setSummary(shortDateFormat.format(dummyDate)); + mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate)); + + } + */ + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - + + if (DEBUG) Log.d(TAG, "onSizeChanged: " + oldw + "x" + oldh + " to " + w + "x" + h); + + if (mLastWidth == w && mLastHeight == h) { + return; + } + int textHeight = mTextDescent - mTextAscent; int headerTextHeight = mHeaderTextDescent - mHeaderTextAscent; - mThinLineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, - 2, getResources().getDisplayMetrics()); if (h > (textHeight*12)) { mLargeMode = true; if (h > (textHeight*15)) { @@ -511,7 +672,6 @@ public class BatteryHistoryChart extends View { // Compress lines to make more room for chart. mLineWidth = textHeight/3; } - mLevelTop = headerTextHeight*2 + mLineWidth; mScreenOnPaint.setARGB(255, 32, 64, 255); mGpsOnPaint.setARGB(255, 32, 64, 255); mWifiRunningPaint.setARGB(255, 32, 64, 255); @@ -519,13 +679,18 @@ public class BatteryHistoryChart extends View { } else { mLargeMode = false; mLineWidth = mThinLineWidth; - mLevelTop = headerTextHeight*2 + mLineWidth; mScreenOnPaint.setARGB(255, 0, 0, 255); mGpsOnPaint.setARGB(255, 0, 0, 255); mWifiRunningPaint.setARGB(255, 0, 0, 255); mCpuRunningPaint.setARGB(255, 0, 0, 255); } if (mLineWidth <= 0) mLineWidth = 1; + + mLevelTop = headerTextHeight*2 - mTextAscent; + mLevelLeft = mMaxPercentLabelStringWidth + mThinLineWidth*3; + mLevelRight = w; + int levelWidth = mLevelRight-mLevelLeft; + mTextPaint.setStrokeWidth(mThinLineWidth); mBatteryGoodPaint.setStrokeWidth(mThinLineWidth); mBatteryWarnPaint.setStrokeWidth(mThinLineWidth); @@ -535,26 +700,26 @@ public class BatteryHistoryChart extends View { mGpsOnPaint.setStrokeWidth(mLineWidth); mWifiRunningPaint.setStrokeWidth(mLineWidth); mCpuRunningPaint.setStrokeWidth(mLineWidth); + mDebugRectPaint.setStrokeWidth(1); + + int fullBarOffset = textHeight + mLineWidth; if (mLargeMode) { - int barOffset = textHeight + mLineWidth; mChargingOffset = mLineWidth; - mScreenOnOffset = mChargingOffset + barOffset; - mCpuRunningOffset = mScreenOnOffset + barOffset; - mWifiRunningOffset = mCpuRunningOffset + barOffset; - mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? barOffset : 0); - mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? barOffset : 0); - mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? barOffset : 0) - + ((mLineWidth*3)/2); + mScreenOnOffset = mChargingOffset + fullBarOffset; + mCpuRunningOffset = mScreenOnOffset + fullBarOffset; + mWifiRunningOffset = mCpuRunningOffset + fullBarOffset; + mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? fullBarOffset : 0); + mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? fullBarOffset : 0); + mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? fullBarOffset : 0) + + mLineWidth*2 + mLineWidth/2; if (mHavePhoneSignal) { mPhoneSignalChart.init(w); } } else { mScreenOnOffset = mGpsOnOffset = mWifiRunningOffset - = mCpuRunningOffset = mLineWidth; - mChargingOffset = mLineWidth*2; - mPhoneSignalOffset = 0; - mLevelOffset = mLineWidth*3; + = mCpuRunningOffset = mChargingOffset = mPhoneSignalOffset = 0; + mLevelOffset = fullBarOffset + mThinLineWidth*4; if (mHavePhoneSignal) { mPhoneSignalChart.init(0); } @@ -563,23 +728,26 @@ public class BatteryHistoryChart extends View { mBatLevelPath.reset(); mBatGoodPath.reset(); mBatWarnPath.reset(); + mTimeRemainPath.reset(); mBatCriticalPath.reset(); mScreenOnPath.reset(); mGpsOnPath.reset(); mWifiRunningPath.reset(); mCpuRunningPath.reset(); mChargingPath.reset(); - - final long timeStart = mHistStart; - final long timeChange = mHistEnd-mHistStart; - + + final long walltimeStart = mStartWallTime; + final long walltimeChange = mEndWallTime-walltimeStart; + long curWalltime = 0; + long lastRealtime = 0; + final int batLow = mBatLow; final int batChange = mBatHigh-mBatLow; - + final int levelh = h - mLevelOffset - mLevelTop; mLevelBottom = mLevelTop + levelh; - - int x = 0, y = 0, startX = 0, lastX = -1, lastY = -1; + + int x = mLevelLeft, y = 0, startX = mLevelLeft, lastX = -1, lastY = -1; int i = 0; Path curLevelPath = null; Path lastLinePath = null; @@ -589,8 +757,25 @@ public class BatteryHistoryChart extends View { if (mStats.startIteratingHistoryLocked()) { final HistoryItem rec = new HistoryItem(); while (mStats.getNextHistoryLocked(rec) && i < N) { - if (rec.isDeltaData()) { - x = (int)(((rec.time-timeStart)*w)/timeChange); + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME || rec.cmd == HistoryItem.CMD_RESET) { + curWalltime = rec.currentTime; + lastRealtime = rec.time; + } else if (curWalltime != 0) { + curWalltime += rec.time-lastRealtime; + lastRealtime = rec.time; + } + if (curWalltime != 0 && rec.isDeltaData()) { + x = mLevelLeft + (int)(((curWalltime-walltimeStart)*levelWidth)/walltimeChange); + if (false) { + StringBuilder sb = new StringBuilder(128); + sb.append("walloff="); + TimeUtils.formatDuration(curWalltime - walltimeStart, sb); + sb.append(" wallchange="); + TimeUtils.formatDuration(walltimeChange, sb); + sb.append(" x="); + sb.append(x); + Log.d("foo", sb.toString()); + } y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange; if (lastX != x) { @@ -625,78 +810,81 @@ public class BatteryHistoryChart extends View { } } - final boolean charging = - (rec.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0; - if (charging != lastCharging) { - if (charging) { - mChargingPath.moveTo(x, h-mChargingOffset); - } else { - mChargingPath.lineTo(x, h-mChargingOffset); + if (mLargeMode) { + final boolean charging = + (rec.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) != 0; + if (charging != lastCharging) { + if (charging) { + mChargingPath.moveTo(x, h-mChargingOffset); + } else { + mChargingPath.lineTo(x, h-mChargingOffset); + } + lastCharging = charging; } - lastCharging = charging; - } - final boolean screenOn = - (rec.states&HistoryItem.STATE_SCREEN_ON_FLAG) != 0; - if (screenOn != lastScreenOn) { - if (screenOn) { - mScreenOnPath.moveTo(x, h-mScreenOnOffset); - } else { - mScreenOnPath.lineTo(x, h-mScreenOnOffset); + final boolean screenOn = + (rec.states&HistoryItem.STATE_SCREEN_ON_FLAG) != 0; + if (screenOn != lastScreenOn) { + if (screenOn) { + mScreenOnPath.moveTo(x, h-mScreenOnOffset); + } else { + mScreenOnPath.lineTo(x, h-mScreenOnOffset); + } + lastScreenOn = screenOn; } - lastScreenOn = screenOn; - } - final boolean gpsOn = - (rec.states&HistoryItem.STATE_GPS_ON_FLAG) != 0; - if (gpsOn != lastGpsOn) { - if (gpsOn) { - mGpsOnPath.moveTo(x, h-mGpsOnOffset); - } else { - mGpsOnPath.lineTo(x, h-mGpsOnOffset); + final boolean gpsOn = + (rec.states&HistoryItem.STATE_GPS_ON_FLAG) != 0; + if (gpsOn != lastGpsOn) { + if (gpsOn) { + mGpsOnPath.moveTo(x, h-mGpsOnOffset); + } else { + mGpsOnPath.lineTo(x, h-mGpsOnOffset); + } + lastGpsOn = gpsOn; } - lastGpsOn = gpsOn; - } - final boolean wifiRunning = - (rec.states&HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0; - if (wifiRunning != lastWifiRunning) { - if (wifiRunning) { - mWifiRunningPath.moveTo(x, h-mWifiRunningOffset); - } else { - mWifiRunningPath.lineTo(x, h-mWifiRunningOffset); + final boolean wifiRunning = + (rec.states&HistoryItem.STATE_WIFI_RUNNING_FLAG) != 0; + if (wifiRunning != lastWifiRunning) { + if (wifiRunning) { + mWifiRunningPath.moveTo(x, h-mWifiRunningOffset); + } else { + mWifiRunningPath.lineTo(x, h-mWifiRunningOffset); + } + lastWifiRunning = wifiRunning; } - lastWifiRunning = wifiRunning; - } - final boolean cpuRunning = - (rec.states&HistoryItem.STATE_CPU_RUNNING_FLAG) != 0; - if (cpuRunning != lastCpuRunning) { - if (cpuRunning) { - mCpuRunningPath.moveTo(x, h - mCpuRunningOffset); - } else { - mCpuRunningPath.lineTo(x, h - mCpuRunningOffset); + final boolean cpuRunning = + (rec.states&HistoryItem.STATE_CPU_RUNNING_FLAG) != 0; + if (cpuRunning != lastCpuRunning) { + if (cpuRunning) { + mCpuRunningPath.moveTo(x, h - mCpuRunningOffset); + } else { + mCpuRunningPath.lineTo(x, h - mCpuRunningOffset); + } + lastCpuRunning = cpuRunning; } - lastCpuRunning = cpuRunning; - } - if (mLargeMode && mHavePhoneSignal) { - int bin; - if (((rec.states&HistoryItem.STATE_PHONE_STATE_MASK) - >> HistoryItem.STATE_PHONE_STATE_SHIFT) - == ServiceState.STATE_POWER_OFF) { - bin = 0; - } else if ((rec.states&HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) { - bin = 1; - } else { - bin = (rec.states&HistoryItem.STATE_SIGNAL_STRENGTH_MASK) - >> HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT; - bin += 2; + if (mLargeMode && mHavePhoneSignal) { + int bin; + if (((rec.states&HistoryItem.STATE_PHONE_STATE_MASK) + >> HistoryItem.STATE_PHONE_STATE_SHIFT) + == ServiceState.STATE_POWER_OFF) { + bin = 0; + } else if ((rec.states&HistoryItem.STATE_PHONE_SCANNING_FLAG) != 0) { + bin = 1; + } else { + bin = (rec.states&HistoryItem.STATE_SIGNAL_STRENGTH_MASK) + >> HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT; + bin += 2; + } + mPhoneSignalChart.addTick(x, bin); } - mPhoneSignalChart.addTick(x, bin); } - } else if (rec.cmd != BatteryStats.HistoryItem.CMD_OVERFLOW) { + } else if (rec.cmd != HistoryItem.CMD_OVERFLOW + && rec.cmd != HistoryItem.CMD_CURRENT_TIME) { if (curLevelPath != null) { finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, @@ -711,83 +899,241 @@ public class BatteryHistoryChart extends View { i++; } } - - finishPaths(w, h, levelh, startX, lastY, curLevelPath, lastX, + + // Figure out where the actual data ends on the screen. + x = mLevelLeft + (int)(((mEndDataWallTime-walltimeStart)*levelWidth)/walltimeChange); + + finishPaths(x, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, lastCpuRunning, lastLinePath); + + if (x < w) { + // If we reserved room for the remaining time, create a final path to draw + // that part of the UI. + mTimeRemainPath.moveTo(x, lastY); + int fullY = mLevelTop + levelh - ((100-batLow)*(levelh-1))/batChange; + int emptyY = mLevelTop + levelh - ((0-batLow)*(levelh-1))/batChange; + if (mDischarging) { + mTimeRemainPath.lineTo(mLevelRight, emptyY); + } else { + mTimeRemainPath.lineTo(mLevelRight, fullY); + mTimeRemainPath.lineTo(mLevelRight, emptyY); + } + mTimeRemainPath.lineTo(x, emptyY); + mTimeRemainPath.close(); + } + + // Create the time labels at the bottom. + mTimeLabels.clear(); + boolean is24hr = is24Hour(); + Calendar calStart = Calendar.getInstance(); + calStart.setTimeInMillis(mStartWallTime); + calStart.set(Calendar.MILLISECOND, 0); + calStart.set(Calendar.SECOND, 0); + calStart.set(Calendar.MINUTE, 0); + long startRoundTime = calStart.getTimeInMillis(); + if (startRoundTime < mStartWallTime) { + calStart.set(Calendar.HOUR_OF_DAY, calStart.get(Calendar.HOUR_OF_DAY)+1); + startRoundTime = calStart.getTimeInMillis(); + } + Calendar calEnd = Calendar.getInstance(); + calEnd.setTimeInMillis(mEndWallTime); + calEnd.set(Calendar.MILLISECOND, 0); + calEnd.set(Calendar.SECOND, 0); + calEnd.set(Calendar.MINUTE, 0); + long endRoundTime = calEnd.getTimeInMillis(); + if (startRoundTime < endRoundTime) { + addTimeLabel(calStart, mLevelLeft, mLevelRight, is24hr); + Calendar calMid = Calendar.getInstance(); + calMid.setTimeInMillis(mStartWallTime+((mEndWallTime-mStartWallTime)/2)); + calMid.set(Calendar.MILLISECOND, 0); + calMid.set(Calendar.SECOND, 0); + calMid.set(Calendar.MINUTE, 0); + long calMidMillis = calMid.getTimeInMillis(); + if (calMidMillis > startRoundTime && calMidMillis < endRoundTime) { + addTimeLabel(calMid, mLevelLeft, mLevelRight, is24hr); + } + addTimeLabel(calEnd, mLevelLeft, mLevelRight, is24hr); + } + + // Create the date labels if the chart includes multiple days + mDateLabels.clear(); + if (calStart.get(Calendar.DAY_OF_YEAR) != calEnd.get(Calendar.DAY_OF_YEAR) || + calStart.get(Calendar.YEAR) != calEnd.get(Calendar.YEAR)) { + boolean isDayFirst = isDayFirst(); + calStart.set(Calendar.HOUR_OF_DAY, 0); + startRoundTime = calStart.getTimeInMillis(); + if (startRoundTime < mStartWallTime) { + calStart.set(Calendar.DAY_OF_YEAR, calStart.get(Calendar.DAY_OF_YEAR) + 1); + startRoundTime = calStart.getTimeInMillis(); + } + calEnd.set(Calendar.HOUR_OF_DAY, 0); + endRoundTime = calEnd.getTimeInMillis(); + if (startRoundTime < endRoundTime) { + addDateLabel(calStart, mLevelLeft, mLevelRight, isDayFirst); + } + addDateLabel(calEnd, mLevelLeft, mLevelRight, isDayFirst); + } } - + + void addTimeLabel(Calendar cal, int levelLeft, int levelRight, boolean is24hr) { + final long walltimeStart = mStartWallTime; + final long walltimeChange = mEndWallTime-walltimeStart; + mTimeLabels.add(new TimeLabel(getContext(), mTextPaint, + levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft)) + / walltimeChange), + cal, is24hr)); + } + + void addDateLabel(Calendar cal, int levelLeft, int levelRight, boolean isDayFirst) { + final long walltimeStart = mStartWallTime; + final long walltimeChange = mEndWallTime-walltimeStart; + mDateLabels.add(new DateLabel(getContext(), mTextPaint, + levelLeft + (int)(((cal.getTimeInMillis()-walltimeStart)*(levelRight-levelLeft)) + / walltimeChange), + cal, isDayFirst)); + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); final int width = getWidth(); final int height = getHeight(); + + if (DEBUG) Log.d(TAG, "onDraw: " + width + "x" + height); + final boolean layoutRtl = isLayoutRtl(); final int textStartX = layoutRtl ? width : 0; final int textEndX = layoutRtl ? 0 : width; final Paint.Align textAlignLeft = layoutRtl ? Paint.Align.RIGHT : Paint.Align.LEFT; final Paint.Align textAlignRight = layoutRtl ? Paint.Align.LEFT : Paint.Align.RIGHT; - mTextPaint.setTextAlign(textAlignLeft); + if (DEBUG) { + canvas.drawRect(1, 1, width, height, mDebugRectPaint); + } + + if (DEBUG) Log.d(TAG, "Drawing level path."); canvas.drawPath(mBatLevelPath, mBatteryBackgroundPaint); + if (!mTimeRemainPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing time remain path."); + canvas.drawPath(mTimeRemainPath, mTimeRemainPaint); + } int durationHalfWidth = mDurationStringWidth / 2; if (layoutRtl) durationHalfWidth = -durationHalfWidth; - if (mLargeMode) { - canvas.drawText(mDurationString, (width / 2) - durationHalfWidth, - mLevelBottom - mTextAscent + mThinLineWidth, mTextPaint); - } else { - canvas.drawText(mDurationString, (width / 2) - durationHalfWidth, - mLevelTop + ((height-mLevelTop) / 2) - ((mTextDescent - mTextAscent) / 2) - - mTextAscent, mTextPaint); + if (mTimeLabels.size() > 0) { + int y = mLevelBottom - mTextAscent + (mThinLineWidth*4); + int ytick = mLevelBottom+mThinLineWidth+(mThinLineWidth/2); + mTextPaint.setTextAlign(Paint.Align.LEFT); + int lastX = 0; + for (int i=0; i<mTimeLabels.size(); i++) { + TimeLabel label = mTimeLabels.get(i); + if (i == 0) { + int x = label.x - label.width/2; + if (x < 0) { + x = 0; + } + if (DEBUG) Log.d(TAG, "Drawing left label: " + label.label + " @ " + x); + canvas.drawText(label.label, x, y, mTextPaint); + canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint); + lastX = x + label.width; + } else if (i < (mTimeLabels.size()-1)) { + int x = label.x - label.width/2; + if (x < (lastX+mTextAscent)) { + continue; + } + TimeLabel nextLabel = mTimeLabels.get(i+1); + if (x > (width-nextLabel.width-mTextAscent)) { + continue; + } + if (DEBUG) Log.d(TAG, "Drawing middle label: " + label.label + " @ " + x); + canvas.drawText(label.label, x, y, mTextPaint); + canvas.drawLine(label.x, ytick, label.x, ytick + mThinLineWidth, mTextPaint); + lastX = x + label.width; + } else { + int x = label.x - label.width/2; + if ((x+label.width) >= width) { + x = width-1-label.width; + } + if (DEBUG) Log.d(TAG, "Drawing right label: " + label.label + " @ " + x); + canvas.drawText(label.label, x, y, mTextPaint); + canvas.drawLine(label.x, ytick, label.x, ytick+mThinLineWidth, mTextPaint); + } + } } - int headerTop = mLevelTop/2 + (mHeaderTextDescent-mHeaderTextAscent)/2; + if (false) { + // Old code for printing label. + mTextPaint.setTextAlign(textAlignLeft); + if (mLargeMode) { + canvas.drawText(mDurationString, (width / 2) - durationHalfWidth, + mLevelBottom - mTextAscent + mThinLineWidth, mTextPaint); + } else { + canvas.drawText(mDurationString, (width / 2) - durationHalfWidth, + mLevelTop + ((height-mLevelTop) / 2) - ((mTextDescent - mTextAscent) / 2) + - mTextAscent, mTextPaint); + } + } + + int headerTop = -mHeaderTextAscent + (mHeaderTextDescent-mHeaderTextAscent)/3; mHeaderTextPaint.setTextAlign(textAlignLeft); + if (DEBUG) Log.d(TAG, "Drawing charge label string: " + mChargeLabelString); canvas.drawText(mChargeLabelString, textStartX, headerTop, mHeaderTextPaint); durationHalfWidth = mChargeDurationStringWidth / 2; if (layoutRtl) durationHalfWidth = -durationHalfWidth; int headerCenter = ((width-mChargeDurationStringWidth-mDrainStringWidth)/2) + (layoutRtl ? mDrainStringWidth : mChargeLabelStringWidth); + if (DEBUG) Log.d(TAG, "Drawing charge duration string: " + mChargeDurationString); canvas.drawText(mChargeDurationString, headerCenter - durationHalfWidth, headerTop, mHeaderTextPaint); mHeaderTextPaint.setTextAlign(textAlignRight); + if (DEBUG) Log.d(TAG, "Drawing drain string: " + mDrainString); canvas.drawText(mDrainString, textEndX, headerTop, mHeaderTextPaint); if (!mBatGoodPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing good battery path"); canvas.drawPath(mBatGoodPath, mBatteryGoodPaint); } if (!mBatWarnPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing warn battery path"); canvas.drawPath(mBatWarnPath, mBatteryWarnPaint); } if (!mBatCriticalPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing critical battery path"); canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint); } if (mHavePhoneSignal) { + if (DEBUG) Log.d(TAG, "Drawing phone signal path"); int top = height-mPhoneSignalOffset - (mLineWidth/2); mPhoneSignalChart.draw(canvas, top, mLineWidth); } if (!mScreenOnPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing screen on path"); canvas.drawPath(mScreenOnPath, mScreenOnPaint); } if (!mChargingPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing charging path"); canvas.drawPath(mChargingPath, mChargingPaint); } if (mHaveGps) { if (!mGpsOnPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing gps path"); canvas.drawPath(mGpsOnPath, mGpsOnPaint); } } if (mHaveWifi) { if (!mWifiRunningPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing wifi path"); canvas.drawPath(mWifiRunningPath, mWifiRunningPaint); } } if (!mCpuRunningPath.isEmpty()) { + if (DEBUG) Log.d(TAG, "Drawing running path"); canvas.drawPath(mCpuRunningPath, mCpuRunningPaint); } if (mLargeMode) { + if (DEBUG) Log.d(TAG, "Drawing large mode labels"); if (mHavePhoneSignal) { canvas.drawText(mPhoneSignalLabel, textStartX, height - mPhoneSignalOffset - mTextDescent, mTextPaint); @@ -806,13 +1152,52 @@ public class BatteryHistoryChart extends View { height - mChargingOffset - mTextDescent, mTextPaint); canvas.drawText(mScreenOnLabel, textStartX, height - mScreenOnOffset - mTextDescent, mTextPaint); - canvas.drawLine(0, mLevelBottom+(mThinLineWidth/2), width, - mLevelBottom+(mThinLineWidth/2), mTextPaint); - canvas.drawLine(0, mLevelTop, 0, - mLevelBottom+(mThinLineWidth/2), mTextPaint); + } + + canvas.drawLine(mLevelLeft-mThinLineWidth, mLevelTop, mLevelLeft-mThinLineWidth, + mLevelBottom+(mThinLineWidth/2), mTextPaint); + if (mLargeMode) { for (int i=0; i<10; i++) { - int y = mLevelTop + ((mLevelBottom-mLevelTop)*i)/10; - canvas.drawLine(0, y, mThinLineWidth*2, y, mTextPaint); + int y = mLevelTop + mThinLineWidth/2 + ((mLevelBottom-mLevelTop)*i)/10; + canvas.drawLine(mLevelLeft-mThinLineWidth*2-mThinLineWidth/2, y, + mLevelLeft-mThinLineWidth-mThinLineWidth/2, y, mTextPaint); + } + } + if (DEBUG) Log.d(TAG, "Drawing max percent, origw=" + mMaxPercentLabelStringWidth + + ", noww=" + (int)mTextPaint.measureText(mMaxPercentLabelString)); + canvas.drawText(mMaxPercentLabelString, 0, mLevelTop, mTextPaint); + canvas.drawText(mMinPercentLabelString, + mMaxPercentLabelStringWidth-mMinPercentLabelStringWidth, + mLevelBottom - mThinLineWidth, mTextPaint); + canvas.drawLine(0, mLevelBottom+mThinLineWidth, width, + mLevelBottom+mThinLineWidth, mTextPaint); + + if (mDateLabels.size() > 0) { + int ytop = mLevelTop + mTextAscent; + int ybottom = mLevelBottom; + int lastLeft = mLevelRight; + mTextPaint.setTextAlign(Paint.Align.LEFT); + for (int i=mDateLabels.size()-1; i>=0; i--) { + DateLabel label = mDateLabels.get(i); + int left = label.x - mThinLineWidth; + int x = label.x + mThinLineWidth*2; + if ((x+label.width) >= lastLeft) { + x = label.x - mThinLineWidth*2 - label.width; + left = x - mThinLineWidth; + if (left >= lastLeft) { + // okay we give up. + continue; + } + } + if (left < mLevelLeft) { + // Won't fit on left, give up. + continue; + } + mDateLinePath.reset(); + mDateLinePath.moveTo(label.x, ytop); + mDateLinePath.lineTo(label.x, ybottom); + canvas.drawPath(mDateLinePath, mDateLinePaint); + canvas.drawText(label.label, x, ytop - mTextAscent, mTextPaint); } } } diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 87e5d76f4..e6c2c9687 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -21,7 +21,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.Handler; diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java index 3f37f6d02..247180119 100644 --- a/src/com/android/settings/notification/NotificationStation.java +++ b/src/com/android/settings/notification/NotificationStation.java @@ -74,10 +74,6 @@ public class NotificationStation extends SettingsPreferenceFragment { private NotificationListenerService mListener = new NotificationListenerService() { @Override - public void onListenerConnected(String[] notificationKeys) { - // noop - } - @Override public void onNotificationPosted(StatusBarNotification notification) { Log.v(TAG, "onNotificationPosted: " + notification); final Handler h = getListView().getHandler(); diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java index 81706c909..688fc6396 100644 --- a/src/com/android/settings/wifi/AccessPoint.java +++ b/src/com/android/settings/wifi/AccessPoint.java @@ -69,6 +69,8 @@ class AccessPoint extends Preference { /* package */ScanResult mScanResult; private int mRssi = Integer.MAX_VALUE; + private long mSeen = 0; + private WifiInfo mInfo; private DetailedState mState; @@ -262,6 +264,9 @@ class AccessPoint extends Preference { } boolean update(ScanResult result) { + if (result.seen > mSeen) { + mSeen = result.seen; + } if (ssid.equals(result.SSID) && security == getSecurity(result)) { if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) { int oldLevel = getLevel(); @@ -333,29 +338,57 @@ class AccessPoint extends Preference { return "\"" + string + "\""; } + /** visibility status of the WifiConfiguration + * @return RSSI and update indicator + * TODO: indicate both 2.4 and 5GHz RSSI as well as number of results + * ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"] + * For instance [-40,5/-30,2] + */ + private String getVisibilityStatus() { + String visibility ; + long now = System.currentTimeMillis(); + long age = (now - mSeen); + if (age < 1000000) { + //show age in seconds, in the form xx + visibility = Long.toString((age / 1000) % 1000); + } else { + //not seen for more than 1000 seconds + visibility = "!"; + } + if (mRssi != Integer.MAX_VALUE) { + visibility = visibility + ", " + Integer.toString(mRssi); + } + return visibility; + } + /** Updates the title and summary; may indirectly call notifyChanged() */ private void refresh() { setTitle(ssid); + StringBuilder summary = new StringBuilder(); Context context = getContext(); - if (mConfig != null && mConfig.status == WifiConfiguration.Status.DISABLED) { - switch (mConfig.disableReason) { - case WifiConfiguration.DISABLED_AUTH_FAILURE: - setSummary(context.getString(R.string.wifi_disabled_password_failure)); - break; - case WifiConfiguration.DISABLED_DHCP_FAILURE: - case WifiConfiguration.DISABLED_DNS_FAILURE: - setSummary(context.getString(R.string.wifi_disabled_network_failure)); - break; - case WifiConfiguration.DISABLED_UNKNOWN_REASON: - setSummary(context.getString(R.string.wifi_disabled_generic)); + if (mConfig != null && (mConfig.status == WifiConfiguration.Status.DISABLED + || mConfig.autoJoinStatus != WifiConfiguration.AUTO_JOIN_ENABLED)) { + if (mConfig.autoJoinStatus != WifiConfiguration.AUTO_JOIN_ENABLED) { + summary.append(context.getString(R.string.wifi_disabled_password_failure)); + } else { + switch (mConfig.disableReason) { + case WifiConfiguration.DISABLED_AUTH_FAILURE: + summary.append(context.getString(R.string.wifi_disabled_password_failure)); + break; + case WifiConfiguration.DISABLED_DHCP_FAILURE: + case WifiConfiguration.DISABLED_DNS_FAILURE: + summary.append(context.getString(R.string.wifi_disabled_network_failure)); + break; + case WifiConfiguration.DISABLED_UNKNOWN_REASON: + summary.append(context.getString(R.string.wifi_disabled_generic)); + } } } else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range - setSummary(context.getString(R.string.wifi_not_in_range)); + summary.append(context.getString(R.string.wifi_not_in_range)); } else if (mState != null) { // This is the active connection - setSummary(Summary.get(context, mState)); + summary.append(Summary.get(context, mState)); } else { // In range, not disabled. - StringBuilder summary = new StringBuilder(); if (mConfig != null) { // Is saved network summary.append(context.getString(R.string.wifi_remembered)); } @@ -377,8 +410,13 @@ class AccessPoint extends Preference { summary.append(context.getString(R.string.wifi_wps_available_second_item)); } } - setSummary(summary.toString()); } + if (WifiSettings.mVerboseLogging > 0) { + //add RSSI/band information for this config, what was seen up to 6 seconds ago + //verbose WiFi Logging is only turned on thru developers settings + summary.append(" " + getVisibilityStatus()); + } + setSummary(summary.toString()); } /** diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 7ccfc6bef..877979806 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -29,6 +29,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkUtils; import android.net.ProxyInfo; import android.net.RouteInfo; +import android.net.Uri; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.AuthAlgorithm; import android.net.wifi.WifiConfiguration.KeyMgmt; @@ -105,6 +106,7 @@ public class WifiConfigController implements TextWatcher, /* These values come from "wifi_proxy_settings" resource array */ public static final int PROXY_NONE = 0; public static final int PROXY_STATIC = 1; + public static final int PROXY_PAC = 2; /* These values come from "wifi_eap_method" resource array */ public static final int WIFI_EAP_METHOD_PEAP = 0; @@ -130,6 +132,7 @@ public class WifiConfigController implements TextWatcher, private TextView mProxyHostView; private TextView mProxyPortView; private TextView mProxyExclusionListView; + private TextView mProxyPacView; private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED; private ProxySettings mProxySettings = ProxySettings.UNASSIGNED; @@ -257,11 +260,7 @@ public class WifiConfigController implements TextWatcher, mProxySettingsSpinner.setSelection(PROXY_STATIC); showAdvancedFields = true; } else if (config.getProxySettings() == ProxySettings.PAC) { - mProxySettingsSpinner.setVisibility(View.GONE); - TextView textView = (TextView)mView.findViewById(R.id.proxy_pac_info); - textView.setVisibility(View.VISIBLE); - textView.setText(context.getString(R.string.proxy_url) + - config.getLinkProperties().getHttpProxy().getPacFileUrl()); + mProxySettingsSpinner.setSelection(PROXY_PAC); showAdvancedFields = true; } else { mProxySettingsSpinner.setSelection(PROXY_NONE); @@ -466,11 +465,10 @@ public class WifiConfigController implements TextWatcher, } } - mProxySettings = (mProxySettingsSpinner != null && - mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) ? - ProxySettings.STATIC : ProxySettings.NONE; - - if (mProxySettings == ProxySettings.STATIC && mProxyHostView != null) { + final int selectedPosition = mProxySettingsSpinner.getSelectedItemPosition(); + mProxySettings = ProxySettings.NONE; + if (selectedPosition == PROXY_STATIC && mProxyHostView != null) { + mProxySettings = ProxySettings.STATIC; String host = mProxyHostView.getText().toString(); String portStr = mProxyPortView.getText().toString(); String exclusionList = mProxyExclusionListView.getText().toString(); @@ -488,6 +486,18 @@ public class WifiConfigController implements TextWatcher, } else { return false; } + } else if (selectedPosition == PROXY_PAC && mProxyPacView != null) { + mProxySettings = ProxySettings.PAC; + CharSequence uriSequence = mProxyPacView.getText(); + if (TextUtils.isEmpty(uriSequence)) { + return false; + } + Uri uri = Uri.parse(uriSequence.toString()); + if (uri == null) { + return false; + } + ProxyInfo proxyInfo = new ProxyInfo(uri); + mLinkProperties.setHttpProxy(proxyInfo); } return true; } @@ -811,8 +821,9 @@ public class WifiConfigController implements TextWatcher, } if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) { - mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.VISIBLE); - mView.findViewById(R.id.proxy_fields).setVisibility(View.VISIBLE); + setVisibility(R.id.proxy_warning_limited_support, View.VISIBLE); + setVisibility(R.id.proxy_fields, View.VISIBLE); + setVisibility(R.id.proxy_pac_field, View.GONE); if (mProxyHostView == null) { mProxyHostView = (TextView) mView.findViewById(R.id.proxy_hostname); mProxyHostView.addTextChangedListener(this); @@ -829,13 +840,34 @@ public class WifiConfigController implements TextWatcher, mProxyExclusionListView.setText(proxyProperties.getExclusionListAsString()); } } + } else if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_PAC) { + setVisibility(R.id.proxy_warning_limited_support, View.GONE); + setVisibility(R.id.proxy_fields, View.GONE); + setVisibility(R.id.proxy_pac_field, View.VISIBLE); + + if (mProxyPacView == null) { + mProxyPacView = (TextView) mView.findViewById(R.id.proxy_pac); + mProxyPacView.addTextChangedListener(this); + } + if (config != null) { + ProxyInfo proxyInfo = config.getLinkProperties().getHttpProxy(); + if (proxyInfo != null) { + mProxyPacView.setText(proxyInfo.getPacFileUrl().toString()); + } + } } else { - mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.GONE); - mView.findViewById(R.id.proxy_fields).setVisibility(View.GONE); + setVisibility(R.id.proxy_warning_limited_support, View.GONE); + setVisibility(R.id.proxy_fields, View.GONE); + setVisibility(R.id.proxy_pac_field, View.GONE); } } - + private void setVisibility(int id, int visibility) { + final View v = mView.findViewById(id); + if (v != null) { + v.setVisibility(visibility); + } + } private void loadCertificates(Spinner spinner, String prefix) { final Context context = mConfigUi.getContext(); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 00a5b900b..604275ad4 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -712,6 +712,8 @@ public class WifiSettings extends RestrictedSettingsFragment return super.onCreateDialog(dialogId); } + /** verbose logging flag is set only thru developer debugging options */ + public static int mVerboseLogging = 0; /** * Shows the latest access points available with supplimental information like * the strength of network and the security for it. @@ -726,6 +728,9 @@ public class WifiSettings extends RestrictedSettingsFragment } final int wifiState = mWifiManager.getWifiState(); + //check if verbose logging has been turned on or off + mVerboseLogging = mWifiManager.getVerboseLoggingLevel(); + switch (wifiState) { case WifiManager.WIFI_STATE_ENABLED: // AccessPoints are automatically sorted with TreeSet. |