diff options
Diffstat (limited to 'src')
5 files changed, 405 insertions, 206 deletions
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java index 1f94d0a..8924b29 100644 --- a/src/com/android/settings/applications/ApplicationsState.java +++ b/src/com/android/settings/applications/ApplicationsState.java @@ -42,6 +42,7 @@ public class ApplicationsState { public static interface Callbacks { public void onRunningStateChanged(boolean running); public void onPackageListChanged(); + public void onRebuildComplete(ArrayList<AppEntry> apps); public void onPackageIconChanged(); public void onPackageSizeChanged(String packageName); public void onAllSizesComputed(); @@ -154,6 +155,14 @@ public class ApplicationsState { long mCurId = 1; String mCurComputingSizePkg; + // Rebuilding of app list. Synchronized on mRebuildSync. + final Object mRebuildSync = new Object(); + boolean mRebuildRequested; + boolean mRebuildAsync; + AppFilter mRebuildFilter; + Comparator<AppEntry> mRebuildComparator; + ArrayList<AppEntry> mRebuildResult; + /** * Receives notifications when applications are added/removed. */ @@ -209,8 +218,9 @@ public class ApplicationsState { } class MainHandler extends Handler { - static final int MSG_PACKAGE_LIST_CHANGED = 1; - static final int MSG_PACKAGE_ICON_CHANGED = 2; + static final int MSG_REBUILD_COMPLETE = 1; + static final int MSG_PACKAGE_LIST_CHANGED = 2; + static final int MSG_PACKAGE_ICON_CHANGED = 3; static final int MSG_PACKAGE_SIZE_CHANGED = 4; static final int MSG_ALL_SIZES_COMPUTED = 5; static final int MSG_RUNNING_STATE_CHANGED = 6; @@ -218,6 +228,11 @@ public class ApplicationsState { @Override public void handleMessage(Message msg) { switch (msg.what) { + case MSG_REBUILD_COMPLETE: { + if (mCurCallbacks != null) { + mCurCallbacks.onRebuildComplete((ArrayList<AppEntry>)msg.obj); + } + } break; case MSG_PACKAGE_LIST_CHANGED: { if (mCurCallbacks != null) { mCurCallbacks.onPackageListChanged(); @@ -305,20 +320,89 @@ public class ApplicationsState { // Creates a new list of app entries with the given filter and comparator. ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator) { - ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>(); + synchronized (mRebuildSync) { + mRebuildRequested = true; + mRebuildAsync = false; + mRebuildFilter = filter; + mRebuildComparator = comparator; + mRebuildResult = null; + if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) { + mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_REBUILD_LIST); + } + + // We will wait for .25s for the list to be built. + long waitend = SystemClock.uptimeMillis()+250; + + while (mRebuildResult == null) { + long now = SystemClock.uptimeMillis(); + if (now >= waitend) { + break; + } + try { + mRebuildSync.wait(waitend - now); + } catch (InterruptedException e) { + } + } + + mRebuildAsync = true; + + return mRebuildResult; + } + } + + void handleRebuildList() { + AppFilter filter; + Comparator<AppEntry> comparator; + synchronized (mRebuildSync) { + if (!mRebuildRequested) { + return; + } + + filter = mRebuildFilter; + comparator = mRebuildComparator; + mRebuildRequested = false; + mRebuildFilter = null; + mRebuildComparator = null; + } + + Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); + + List<ApplicationInfo> apps; synchronized (mEntriesMap) { - if (DEBUG) Log.i(TAG, "Rebuilding..."); - for (int i=0; i<mApplications.size(); i++) { - ApplicationInfo info = mApplications.get(i); - if (filter == null || filter.filterApp(info)) { + apps = new ArrayList<ApplicationInfo>(mApplications); + } + + ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>(); + if (DEBUG) Log.i(TAG, "Rebuilding..."); + for (int i=0; i<apps.size(); i++) { + ApplicationInfo info = apps.get(i); + if (filter == null || filter.filterApp(info)) { + synchronized (mEntriesMap) { AppEntry entry = getEntryLocked(info); if (DEBUG) Log.i(TAG, "Using " + info.packageName + ": " + entry); filteredApps.add(entry); } } } + Collections.sort(filteredApps, comparator); - return filteredApps; + + synchronized (mRebuildSync) { + if (!mRebuildRequested) { + if (!mRebuildAsync) { + mRebuildResult = filteredApps; + mRebuildSync.notifyAll(); + } else { + if (!mMainHandler.hasMessages(MainHandler.MSG_REBUILD_COMPLETE)) { + Message msg = mMainHandler.obtainMessage( + MainHandler.MSG_REBUILD_COMPLETE, filteredApps); + mMainHandler.sendMessage(msg); + } + } + } + } + + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } AppEntry getEntry(String packageName) { @@ -447,9 +531,10 @@ public class ApplicationsState { final HandlerThread mThread; final BackgroundHandler mBackgroundHandler; class BackgroundHandler extends Handler { - static final int MSG_LOAD_ENTRIES = 1; - static final int MSG_LOAD_ICONS = 2; - static final int MSG_LOAD_SIZES = 3; + static final int MSG_REBUILD_LIST = 1; + static final int MSG_LOAD_ENTRIES = 2; + static final int MSG_LOAD_ICONS = 3; + static final int MSG_LOAD_SIZES = 4; boolean mRunning; @@ -498,7 +583,12 @@ public class ApplicationsState { @Override public void handleMessage(Message msg) { + // Always try rebuilding list first thing, if needed. + handleRebuildList(); + switch (msg.what) { + case MSG_REBUILD_LIST: { + } break; case MSG_LOAD_ENTRIES: { int numDone = 0; synchronized (mEntriesMap) { diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index af03549..1583ef1 100644 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -18,6 +18,7 @@ package com.android.settings.applications; import com.android.internal.content.PackageHelper; import com.android.settings.R; +import com.android.settings.applications.ApplicationsState.AppEntry; import android.app.Activity; import android.app.ActivityManager; @@ -385,6 +386,10 @@ public class InstalledAppDetails extends Activity } @Override + public void onRebuildComplete(ArrayList<AppEntry> apps) { + } + + @Override public void onPackageSizeChanged(String packageName) { if (packageName.equals(mAppEntry.info.packageName)) { refreshSizeInfo(); diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 34e0e8e..f8463c3 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -23,6 +23,7 @@ import android.app.TabActivity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; @@ -47,6 +48,7 @@ import android.widget.AdapterView.OnItemClickListener; import java.util.ArrayList; import java.util.Comparator; +import java.util.List; /** * Activity to pick an application that will be used to display installation information and @@ -152,6 +154,7 @@ public class ManageApplications extends TabActivity implements private ArrayList<ApplicationsState.AppEntry> mEntries; private boolean mResumed; private int mLastFilterMode=-1, mLastSortMode=-1; + private boolean mWaitingForData; CharSequence mCurFilterPrefix; private Filter mFilter = new Filter() { @@ -184,7 +187,7 @@ public class ManageApplications extends TabActivity implements mState.resume(this); mLastFilterMode = filter; mLastSortMode = sort; - rebuild(); + rebuild(true); } else { rebuild(filter, sort); } @@ -203,10 +206,10 @@ public class ManageApplications extends TabActivity implements } mLastFilterMode = filter; mLastSortMode = sort; - rebuild(); + rebuild(true); } - public void rebuild() { + public void rebuild(boolean eraseold) { if (DEBUG) Log.i(TAG, "Rebuilding app list..."); ApplicationsState.AppFilter filterObj; Comparator<AppEntry> comparatorObj; @@ -229,9 +232,28 @@ public class ManageApplications extends TabActivity implements comparatorObj = ApplicationsState.ALPHA_COMPARATOR; break; } - mBaseEntries = mState.rebuild(filterObj, comparatorObj); - mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries); + ArrayList<ApplicationsState.AppEntry> entries + = mState.rebuild(filterObj, comparatorObj); + if (entries == null && !eraseold) { + // Don't have new list yet, but can continue using the old one. + return; + } + mBaseEntries = entries; + if (mBaseEntries != null) { + mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries); + } else { + mEntries = null; + } notifyDataSetChanged(); + + if (entries == null) { + mWaitingForData = true; + mListContainer.setVisibility(View.INVISIBLE); + mLoadingContainer.setVisibility(View.VISIBLE); + } else { + mListContainer.setVisibility(View.VISIBLE); + mLoadingContainer.setVisibility(View.GONE); + } } ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix, @@ -260,8 +282,18 @@ public class ManageApplications extends TabActivity implements } @Override + public void onRebuildComplete(ArrayList<AppEntry> apps) { + mListContainer.setVisibility(View.VISIBLE); + mLoadingContainer.setVisibility(View.GONE); + mWaitingForData = false; + mBaseEntries = apps; + mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries); + notifyDataSetChanged(); + } + + @Override public void onPackageListChanged() { - rebuild(); + rebuild(false); } @Override @@ -284,7 +316,7 @@ public class ManageApplications extends TabActivity implements // user viewed, and are sorting by size... they may // have cleared data, so we immediately want to resort // the list with the new size to reflect it to the user. - rebuild(); + rebuild(false); } return; } @@ -294,7 +326,7 @@ public class ManageApplications extends TabActivity implements @Override public void onAllSizesComputed() { if (mLastSortMode == SORT_ORDER_SIZE) { - rebuild(); + rebuild(false); } } @@ -566,6 +598,7 @@ public class ManageApplications extends TabActivity implements if (mCurView != which) { mRunningProcessesView.setVisibility(View.GONE); mListContainer.setVisibility(View.VISIBLE); + mLoadingContainer.setVisibility(View.GONE); } if (mActivityResumed) { mApplicationsAdapter.resume(mFilterApps, mSortOrder); diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java index fd36a9d..a74780d 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -35,6 +35,69 @@ import android.util.TypedValue; import android.view.View; public class BatteryHistoryChart extends View { + static final int CHART_DATA_X_MASK = 0x0000ffff; + static final int CHART_DATA_BIN_MASK = 0xffff0000; + static final int CHART_DATA_BIN_SHIFT = 16; + + static class ChartData { + int[] mColors; + Paint[] mPaints; + + int mNumTicks; + int[] mTicks; + int mLastBin; + + void setColors(int[] colors) { + mColors = colors; + mPaints = new Paint[colors.length]; + for (int i=0; i<colors.length; i++) { + mPaints[i] = new Paint(); + mPaints[i].setColor(colors[i]); + mPaints[i].setStyle(Paint.Style.FILL); + } + } + + void init(int width) { + if (width > 0) { + mTicks = new int[width+2]; + } else { + mTicks = null; + } + mNumTicks = 0; + mLastBin = 0; + } + + void addTick(int x, int bin) { + if (bin != mLastBin) { + mTicks[mNumTicks] = x | bin << CHART_DATA_BIN_SHIFT; + mNumTicks++; + mLastBin = bin; + } + } + + void finish(int width) { + if (mLastBin != 0) { + addTick(width, 0); + } + } + + void draw(Canvas canvas, int top, int height) { + int lastBin=0, lastX=0; + int bottom = top + height; + for (int i=0; i<mNumTicks; i++) { + int tick = mTicks[i]; + int x = tick&CHART_DATA_X_MASK; + int bin = (tick&CHART_DATA_BIN_MASK) >> CHART_DATA_BIN_SHIFT; + if (lastBin != 0) { + canvas.drawRect(lastX, top, x, bottom, mPaints[lastBin]); + } + lastBin = bin; + lastX = x; + } + + } + } + static final int SANS = 1; static final int SERIF = 2; static final int MONOSPACE = 3; @@ -42,7 +105,7 @@ public class BatteryHistoryChart extends View { static final int BATTERY_WARN = 29; static final int BATTERY_CRITICAL = 14; - // First value if for phone off; sirst value is "scanning"; following values + // First value if for phone off; first value is "scanning"; following values // are battery stats signal strength buckets. static final int NUM_PHONE_SIGNALS = 7; @@ -55,11 +118,7 @@ public class BatteryHistoryChart extends View { final Paint mGpsOnPaint = new Paint(); final Paint mWifiRunningPaint = new Paint(); final Paint mWakeLockPaint = new Paint(); - final Paint[] mPhoneSignalPaints = new Paint[NUM_PHONE_SIGNALS]; - final int[] mPhoneSignalColors = new int[] { - 0x00000000, 0xffa00000, 0xffa0a000, 0xff808020, - 0xff808040, 0xff808060, 0xff008000 - }; + final ChartData mPhoneSignalChart = new ChartData(); final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); final Path mBatLevelPath = new Path(); @@ -103,14 +162,11 @@ public class BatteryHistoryChart extends View { int mLevelOffset; int mLevelTop; int mLevelBottom; - static final int PHONE_SIGNAL_X_MASK = 0x0000ffff; - static final int PHONE_SIGNAL_BIN_MASK = 0xffff0000; - static final int PHONE_SIGNAL_BIN_SHIFT = 16; - int mNumPhoneSignalTicks; - int[] mPhoneSignalTicks; + 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; - BatteryStats.HistoryItem mHistFirst; long mHistStart; long mHistEnd; int mBatLow; @@ -131,19 +187,14 @@ public class BatteryHistoryChart extends View { mBatteryCriticalPaint.setStyle(Paint.Style.STROKE); mChargingPaint.setARGB(255, 0, 128, 0); mChargingPaint.setStyle(Paint.Style.STROKE); - mScreenOnPaint.setARGB(255, 0, 0, 255); mScreenOnPaint.setStyle(Paint.Style.STROKE); - mGpsOnPaint.setARGB(255, 0, 0, 255); mGpsOnPaint.setStyle(Paint.Style.STROKE); - mWifiRunningPaint.setARGB(255, 0, 0, 255); mWifiRunningPaint.setStyle(Paint.Style.STROKE); - mWakeLockPaint.setARGB(255, 0, 0, 255); mWakeLockPaint.setStyle(Paint.Style.STROKE); - for (int i=0; i<NUM_PHONE_SIGNALS; i++) { - mPhoneSignalPaints[i] = new Paint(); - mPhoneSignalPaints[i].setColor(mPhoneSignalColors[i]); - mPhoneSignalPaints[i].setStyle(Paint.Style.FILL); - } + mPhoneSignalChart.setColors(new int[] { + 0x00000000, 0xffa00000, 0xffa0a000, 0xff808020, + 0xff808040, 0xff808060, 0xff008000 + }); mTextPaint.density = getResources().getDisplayMetrics().density; mTextPaint.setCompatibilityScaling( @@ -296,29 +347,30 @@ public class BatteryHistoryChart extends View { mWakeLockLabel = getContext().getString(R.string.battery_stats_wake_lock_label); mPhoneSignalLabel = getContext().getString(R.string.battery_stats_phone_signal_label); - BatteryStats.HistoryItem rec = stats.getHistory(); - mHistFirst = null; int pos = 0; int lastInteresting = 0; byte lastLevel = -1; mBatLow = 0; mBatHigh = 100; int aggrStates = 0; - while (rec != null) { - pos++; - if (rec.cmd == HistoryItem.CMD_UPDATE) { - if (mHistFirst == null) { - mHistFirst = rec; - mHistStart = rec.time; - } - if (rec.batteryLevel != lastLevel || pos == 1) { - lastLevel = rec.batteryLevel; - lastInteresting = pos; - mHistEnd = rec.time; + boolean first = true; + if (stats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (stats.getNextHistoryLocked(rec)) { + pos++; + if (rec.cmd == HistoryItem.CMD_UPDATE) { + if (first) { + first = false; + mHistStart = rec.time; + } + if (rec.batteryLevel != lastLevel || pos == 1) { + lastLevel = rec.batteryLevel; + lastInteresting = pos; + mHistEnd = rec.time; + } + aggrStates |= rec.states; } - aggrStates |= rec.states; } - rec = rec.next; } mNumHist = lastInteresting; mHaveGps = (aggrStates&HistoryItem.STATE_GPS_ON_FLAG) != 0; @@ -337,15 +389,9 @@ public class BatteryHistoryChart extends View { mTextDescent = (int)mTextPaint.descent(); } - void addPhoneSignalTick(int x, int bin) { - mPhoneSignalTicks[mNumPhoneSignalTicks] - = x | bin << PHONE_SIGNAL_BIN_SHIFT; - mNumPhoneSignalTicks++; - } - void finishPaths(int w, int h, int levelh, int startX, int y, Path curLevelPath, int lastX, boolean lastCharging, boolean lastScreenOn, boolean lastGpsOn, - boolean lastWifiRunning, boolean lastWakeLock, int lastPhoneSignal, Path lastPath) { + boolean lastWifiRunning, boolean lastWakeLock, Path lastPath) { if (curLevelPath != null) { if (lastX >= 0 && lastX < w) { if (lastPath != null) { @@ -373,9 +419,7 @@ public class BatteryHistoryChart extends View { if (lastWakeLock) { mWakeLockPath.lineTo(w, h-mWakeLockOffset); } - if (lastPhoneSignal != 0) { - addPhoneSignalTick(w, 0); - } + mPhoneSignalChart.finish(w); } @Override @@ -389,10 +433,18 @@ public class BatteryHistoryChart extends View { mLargeMode = true; mLineWidth = textHeight/2; mLevelTop = textHeight + mLineWidth; + mScreenOnPaint.setARGB(255, 32, 64, 255); + mGpsOnPaint.setARGB(255, 32, 64, 255); + mWifiRunningPaint.setARGB(255, 32, 64, 255); + mWakeLockPaint.setARGB(255, 32, 64, 255); } else { mLargeMode = false; mLineWidth = mThinLineWidth; mLevelTop = 0; + mScreenOnPaint.setARGB(255, 0, 0, 255); + mGpsOnPaint.setARGB(255, 0, 0, 255); + mWifiRunningPaint.setARGB(255, 0, 0, 255); + mWakeLockPaint.setARGB(255, 0, 0, 255); } if (mLineWidth <= 0) mLineWidth = 1; mTextPaint.setStrokeWidth(mThinLineWidth); @@ -414,14 +466,14 @@ public class BatteryHistoryChart extends View { mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? barOffset : 0); mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? barOffset : 0); mLevelOffset = mPhoneSignalOffset + barOffset + mLineWidth; - mPhoneSignalTicks = new int[w+2]; + mPhoneSignalChart.init(w); } else { mScreenOnOffset = mGpsOnOffset = mWifiRunningOffset = mWakeLockOffset = mLineWidth; mChargingOffset = mLineWidth*2; mPhoneSignalOffset = 0; mLevelOffset = mLineWidth*3; - mPhoneSignalTicks = null; + mPhoneSignalChart.init(0); } mBatLevelPath.reset(); @@ -443,146 +495,142 @@ public class BatteryHistoryChart extends View { final int levelh = h - mLevelOffset - mLevelTop; mLevelBottom = mLevelTop + levelh; - BatteryStats.HistoryItem rec = mHistFirst; int x = 0, y = 0, startX = 0, lastX = -1, lastY = -1; int i = 0; Path curLevelPath = null; Path lastLinePath = null; boolean lastCharging = false, lastScreenOn = false, lastGpsOn = false; boolean lastWifiRunning = false, lastWakeLock = false; - int lastPhoneSignalBin = 0; final int N = mNumHist; - while (rec != null && i < N) { - if (rec.cmd == BatteryStats.HistoryItem.CMD_UPDATE) { - x = (int)(((rec.time-timeStart)*w)/timeChange); - y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange; - - if (lastX != x) { - // We have moved by at least a pixel. - if (lastY != y) { - // Don't plot changes within a pixel. - Path path; - byte value = rec.batteryLevel; - if (value <= BATTERY_CRITICAL) path = mBatCriticalPath; - else if (value <= BATTERY_WARN) path = mBatWarnPath; - else path = mBatGoodPath; - - if (path != lastLinePath) { - if (lastLinePath != null) { - lastLinePath.lineTo(x, y); + if (mStats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (mStats.getNextHistoryLocked(rec) && i < N) { + if (rec.cmd == BatteryStats.HistoryItem.CMD_UPDATE) { + x = (int)(((rec.time-timeStart)*w)/timeChange); + y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange; + + if (lastX != x) { + // We have moved by at least a pixel. + if (lastY != y) { + // Don't plot changes within a pixel. + Path path; + byte value = rec.batteryLevel; + if (value <= BATTERY_CRITICAL) path = mBatCriticalPath; + else if (value <= BATTERY_WARN) path = mBatWarnPath; + else path = mBatGoodPath; + + if (path != lastLinePath) { + if (lastLinePath != null) { + lastLinePath.lineTo(x, y); + } + path.moveTo(x, y); + lastLinePath = path; + } else { + path.lineTo(x, y); + } + + if (curLevelPath == null) { + curLevelPath = mBatLevelPath; + curLevelPath.moveTo(x, y); + startX = x; + } else { + curLevelPath.lineTo(x, y); } - path.moveTo(x, y); - lastLinePath = path; - } else { - path.lineTo(x, y); + lastX = x; + lastY = y; } - - if (curLevelPath == null) { - curLevelPath = mBatLevelPath; - curLevelPath.moveTo(x, y); - startX = x; - } else { - curLevelPath.lineTo(x, y); + + 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; } - lastX = x; - lastY = y; - } - 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); + 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; } - 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 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; } - 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 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; } - 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 wakeLock = + (rec.states&HistoryItem.STATE_WAKE_LOCK_FLAG) != 0; + if (wakeLock != lastWakeLock) { + if (wakeLock) { + mWakeLockPath.moveTo(x, h-mWakeLockOffset); + } else { + mWakeLockPath.lineTo(x, h-mWakeLockOffset); + } + lastWakeLock = wakeLock; } - lastWifiRunning = wifiRunning; - } - final boolean wakeLock = - (rec.states&HistoryItem.STATE_WAKE_LOCK_FLAG) != 0; - if (wakeLock != lastWakeLock) { - if (wakeLock) { - mWakeLockPath.moveTo(x, h-mWakeLockOffset); - } else { - mWakeLockPath.lineTo(x, h-mWakeLockOffset); + if (mLargeMode) { + 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); } - lastWakeLock = wakeLock; } - if (mLargeMode) { - 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 (bin != lastPhoneSignalBin) { - addPhoneSignalTick(x, bin); - lastPhoneSignalBin = bin; - } + } else if (rec.cmd != BatteryStats.HistoryItem.CMD_OVERFLOW) { + if (curLevelPath != null) { + finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX, + lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, + lastWakeLock, lastLinePath); + lastX = lastY = -1; + curLevelPath = null; + lastLinePath = null; + lastCharging = lastScreenOn = lastGpsOn = lastWakeLock = false; } } - } else if (rec.cmd != BatteryStats.HistoryItem.CMD_OVERFLOW) { - if (curLevelPath != null) { - finishPaths(x+1, h, levelh, startX, lastY, curLevelPath, lastX, - lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, - lastWakeLock, lastPhoneSignalBin, lastLinePath); - lastX = lastY = -1; - curLevelPath = null; - lastLinePath = null; - lastCharging = lastScreenOn = lastGpsOn = lastWakeLock = false; - lastPhoneSignalBin = 0; - } + i++; } - - rec = rec.next; - i++; } finishPaths(w, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastWifiRunning, - lastWakeLock, lastPhoneSignalBin, lastLinePath); + lastWakeLock, lastLinePath); } @Override @@ -611,19 +659,8 @@ public class BatteryHistoryChart extends View { if (!mBatCriticalPath.isEmpty()) { canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint); } - int lastBin=0, lastX=0; int top = height-mPhoneSignalOffset - (mLineWidth/2); - int bottom = top + mLineWidth; - for (int i=0; i<mNumPhoneSignalTicks; i++) { - int tick = mPhoneSignalTicks[i]; - int x = tick&PHONE_SIGNAL_X_MASK; - int bin = (tick&PHONE_SIGNAL_BIN_MASK) >> PHONE_SIGNAL_BIN_SHIFT; - if (lastBin != 0) { - canvas.drawRect(lastX, top, x, bottom, mPhoneSignalPaints[lastBin]); - } - lastBin = bin; - lastX = x; - } + mPhoneSignalChart.draw(canvas, top, mLineWidth); if (!mScreenOnPath.isEmpty()) { canvas.drawPath(mScreenOnPath, mScreenOnPaint); } diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index ac9401d..e0d614d 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -18,7 +18,6 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; import android.hardware.SensorManager; import android.os.BatteryStats; import android.os.Bundle; @@ -70,6 +69,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { BatteryStatsImpl mStats; private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>(); private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>(); + private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>(); private PreferenceGroup mAppListGroup; @@ -82,6 +82,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { private double mMaxPower = 1; private double mTotalPower; private double mWifiPower; + private double mBluetoothPower; private PowerProfile mPowerProfile; // How much the apps together have left WIFI running. @@ -228,6 +229,25 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { sipper.tcpBytesReceived, }; } break; + case BLUETOOTH: + { + types = new int[] { + R.string.usage_type_on_time, + R.string.usage_type_cpu, + R.string.usage_type_cpu_foreground, + R.string.usage_type_wake_lock, + R.string.usage_type_data_send, + R.string.usage_type_data_recv, + }; + values = new double[] { + sipper.usageTime, + sipper.cpuTime, + sipper.cpuFgTime, + sipper.wakeLockTime, + sipper.tcpBytesSent, + sipper.tcpBytesReceived, + }; + } break; default: { types = new int[] { @@ -295,11 +315,13 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { mMaxPower = 0; mTotalPower = 0; mWifiPower = 0; + mBluetoothPower = 0; mAppWifiRunning = 0; mAppListGroup.removeAll(); mUsageList.clear(); mWifiSippers.clear(); + mBluetoothSippers.clear(); processAppUsage(); processMiscUsage(); @@ -400,11 +422,15 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { } cpuTime += tmpCpuTime; power += processPower; - if (highestDrain < processPower) { + if (packageWithHighestDrain == null + || packageWithHighestDrain.startsWith("*")) { + highestDrain = processPower; + packageWithHighestDrain = ent.getKey(); + } else if (highestDrain < processPower + && !ent.getKey().startsWith("*")) { highestDrain = processPower; packageWithHighestDrain = ent.getKey(); } - } if (DEBUG) Log.i(TAG, "Max drain of " + highestDrain + " by " + packageWithHighestDrain); @@ -486,12 +512,16 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { app.tcpBytesSent = tcpBytesSent; if (u.getUid() == Process.WIFI_UID) { mWifiSippers.add(app); + } else if (u.getUid() == Process.BLUETOOTH_GID) { + mBluetoothSippers.add(app); } else { mUsageList.add(app); } } if (u.getUid() == Process.WIFI_UID) { mWifiPower += power; + } else if (u.getUid() == Process.BLUETOOTH_GID) { + mBluetoothPower += power; } else { if (power > mMaxPower) mMaxPower = power; mTotalPower += power; @@ -551,6 +581,20 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { } } + private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) { + for (int i=0; i<from.size(); i++) { + BatterySipper wbs = from.get(i); + if (DEBUG) Log.i(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime); + bs.cpuTime += wbs.cpuTime; + bs.gpsTime += wbs.gpsTime; + bs.wifiRunningTime += wbs.wifiRunningTime; + bs.cpuFgTime += wbs.cpuFgTime; + bs.wakeLockTime += wbs.wakeLockTime; + bs.tcpBytesReceived += wbs.tcpBytesReceived; + bs.tcpBytesSent += wbs.tcpBytesSent; + } + } + private void addWiFiUsage(long uSecNow) { long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; @@ -564,17 +608,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { if (DEBUG) Log.i(TAG, "WIFI power=" + wifiPower + " from procs=" + mWifiPower); BatterySipper bs = addEntry(getString(R.string.power_wifi), DrainType.WIFI, runningTimeMs, R.drawable.ic_settings_wifi, wifiPower + mWifiPower); - for (int i=0; i<mWifiSippers.size(); i++) { - BatterySipper wbs = mWifiSippers.get(i); - if (DEBUG) Log.i(TAG, "WIFI adding sipper " + wbs + ": cpu=" + wbs.cpuTime); - bs.cpuTime += wbs.cpuTime; - bs.gpsTime += wbs.gpsTime; - bs.wifiRunningTime += wbs.wifiRunningTime; - bs.cpuFgTime += wbs.cpuFgTime; - bs.wakeLockTime += wbs.wakeLockTime; - bs.tcpBytesReceived += wbs.tcpBytesReceived; - bs.tcpBytesSent += wbs.tcpBytesSent; - } + aggregateSippers(bs, mWifiSippers, "WIFI"); } private void addIdleUsage(long uSecNow) { @@ -592,9 +626,9 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable { int btPingCount = mStats.getBluetoothPingCount(); btPower += (btPingCount * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; - - addEntry(getString(R.string.power_bluetooth), DrainType.BLUETOOTH, btOnTimeMs, - R.drawable.ic_settings_bluetooth, btPower); + BatterySipper bs = addEntry(getString(R.string.power_bluetooth), DrainType.BLUETOOTH, + btOnTimeMs, R.drawable.ic_settings_bluetooth, btPower + mBluetoothPower); + aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); } private double getAverageDataCost() { |