use of com.asksven.android.common.privateapiproxies.StatElement in project BetterBatteryStats by asksven.
the class AlarmsDumpsys method getAlarmsFrom_5.
protected static ArrayList<StatElement> getAlarmsFrom_5(List<String> res) {
ArrayList<StatElement> myAlarms = null;
long nTotalCount = 0;
if ((res != null) && (res.size() != 0)) {
Pattern begin = Pattern.compile("Alarm Stats");
boolean bParsing = false;
// we are looking for multiline entries in the format
// ' <package name> +<time>ms running, <number> wakeups
// ' +<time>ms <number> wakes <number> alarms: act=<intern> (repeating 1..n times)
Pattern packagePattern = Pattern.compile("\\s\\s.*:([a-z][a-zA-Z0-9\\.]+)\\s\\+(.*), (\\d+) wakeups:");
Pattern numberPattern = Pattern.compile("\\s\\s\\s\\s\\+([0-9a-z]+)ms (\\d+) wakes (\\d+) alarms: (\\*alarm\\*|\\*walarm\\*):(.*)");
myAlarms = new ArrayList<StatElement>();
Alarm myAlarm = null;
// process the file
for (int i = 0; i < res.size(); i++) {
// skip till start mark found
if (bParsing) {
// parse the alarms by block
String line = res.get(i);
Matcher mPackage = packagePattern.matcher(line);
Matcher mNumber = numberPattern.matcher(line);
// first line
if (mPackage.find()) {
try {
// if there was a previous Alarm populated store it
if (myAlarm != null) {
myAlarms.add(myAlarm);
}
// we are interested in the first token
String strPackageName = mPackage.group(1);
myAlarm = new Alarm(strPackageName);
String strWakeups = mPackage.group(3);
long nWakeups = Long.parseLong(strWakeups);
myAlarm.setWakeups(nWakeups);
nTotalCount += nWakeups;
} catch (Exception e) {
Log.e(TAG, "Error: parsing error in package line (" + line + ")");
}
}
// second line (and following till next package)
if (mNumber.find()) {
try {
// we are interested in the first and second token
String strNumber = mNumber.group(2);
String strIntent = mNumber.group(5);
long nNumber = Long.parseLong(strNumber);
if (myAlarm == null) {
Log.e(TAG, "Error: number line found but without alarm object (" + line + ")");
} else {
myAlarm.addItem(nNumber, strIntent);
}
} catch (Exception e) {
Log.e(TAG, "Error: parsing error in number line (" + line + ")");
}
}
} else {
// look for beginning
Matcher line = begin.matcher(res.get(i));
if (line.find()) {
bParsing = true;
}
}
}
// the last populated alarms has not been added to the list yet
myAlarms.add(myAlarm);
} else {
myAlarms = new ArrayList<StatElement>();
Alarm myAlarm = new Alarm(PERMISSION_DENIED);
myAlarm.setWakeups(1);
myAlarms.add(myAlarm);
}
for (int i = 0; i < myAlarms.size(); i++) {
Alarm myAlarm = (Alarm) myAlarms.get(i);
if (myAlarm != null) {
myAlarm.setTotalCount(nTotalCount);
}
}
return myAlarms;
}
use of com.asksven.android.common.privateapiproxies.StatElement in project BetterBatteryStats by asksven.
the class Wakelocks method parseProcWakelocks.
public static ArrayList<StatElement> parseProcWakelocks(Context context) {
if (CommonLogSettings.DEBUG) {
Log.i(TAG, "Parsing " + FILE_PATH);
}
String delimiter = String.valueOf('\t');
ArrayList<StatElement> myRet = new ArrayList<StatElement>();
// format
// [name, count, expire_count, wake_count, active_since, total_time, sleep_time, max_time, last_change]
ArrayList<String[]> rows = parseDelimitedFile(FILE_PATH, delimiter);
long msSinceBoot = SystemClock.elapsedRealtime();
// list the running processes
ActivityManager actvityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> procInfos = actvityManager.getRunningAppProcesses();
PackageManager pack = context.getPackageManager();
// start with 1
for (int i = 1; i < rows.size(); i++) {
try {
// times in file are microseconds
String[] data = (String[]) rows.get(i);
String name = data[0];
int count = Integer.valueOf(data[1]);
int expire_count = Integer.valueOf(data[2]);
int wake_count = Integer.valueOf(data[3]);
long active_since = Long.valueOf(data[4]);
long total_time = Long.valueOf(data[5]) / 1000000;
long sleep_time = Long.valueOf(data[6]) / 1000000;
long max_time = Long.valueOf(data[7]) / 1000000;
long last_change = Long.valueOf(data[8]);
// post-processing of eventX-YYYY processes
String details = "";
// we start with a " here as that is the way the data comes from /proc
if (name.startsWith("\"event")) {
String process = name.replaceAll("\"", "");
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Pattern 'event' found in " + process);
}
int proc = 0;
String[] parts = process.split("-");
if (parts.length == 2) {
try {
proc = Integer.valueOf(parts[1]);
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Resolving proc name for 'event' " + proc);
}
} catch (Exception e) {
Log.e(TAG, "Cound not split process name " + process);
}
}
if (proc != 0) {
// search for the process in the task list
for (int psCount = 0; psCount < procInfos.size(); psCount++) {
int id = procInfos.get(psCount).pid;
if (id == proc) {
String processName = procInfos.get(psCount).processName;
details = processName;
String appName = "";
String[] pkgList = procInfos.get(count).pkgList;
for (int j = 0; j < pkgList.length; j++) {
if (details.length() > 0) {
details += ", ";
}
details += pkgList[j];
}
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Pattern 'event' resolved to " + details);
}
}
}
}
}
NativeKernelWakelock wl = new NativeKernelWakelock(name, details, count, expire_count, wake_count, active_since, total_time, sleep_time, max_time, last_change, msSinceBoot);
myRet.add(wl);
} catch (Exception e) {
// go on
}
}
return myRet;
}
use of com.asksven.android.common.privateapiproxies.StatElement in project BetterBatteryStats by asksven.
the class WakeupSourcesLg method parseWakeupSources.
// private static String FILE_PATH = "/sdcard/wakeup_sources.txt";
public static ArrayList<StatElement> parseWakeupSources(Context context) {
Log.i(TAG, "Parsing " + FILE_PATH);
String delimiter = String.valueOf('\t');
delimiter = delimiter + "+";
ArrayList<StatElement> myRet = new ArrayList<StatElement>();
// format
// new [name active_count event_count wakeup_count expire_count active_since total_time max_time last_change prevent_suspend_time]
ArrayList<String[]> rows = parseDelimitedFile(FILE_PATH, delimiter);
long msSinceBoot = SystemClock.elapsedRealtime();
// list the running processes
ActivityManager actvityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> procInfos = actvityManager.getRunningAppProcesses();
// start with 1
for (int i = 1; i < rows.size(); i++) {
try {
// different mapping from LG G3
// name active_count event_count wakeup_count expire_count pending_count active_since total_time max_time last_change prevent_suspend_time
// times in file are milliseconds
String[] data = (String[]) rows.get(i);
// name
String name = data[0].trim();
// active_count
int count = Integer.valueOf(data[1]);
// expire_count
int expire_count = Integer.valueOf(data[4]);
// wakeup_count
int wake_count = Integer.valueOf(data[3]);
// active_since
long active_since = Long.valueOf(data[6]);
// total_time
long total_time = Long.valueOf(data[7]);
// prevent_suspend_time
long sleep_time = Long.valueOf(data[10]);
// max_time
long max_time = Long.valueOf(data[8]);
// last_change
long last_change = Long.valueOf(data[9]);
// post-processing of eventX-YYYY processes
String details = "";
// we start with a " here as that is the way the data comes from /proc
if (name.startsWith("\"event")) {
String process = name.replaceAll("\"", "");
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Pattern 'event' found in " + process);
}
int proc = 0;
String[] parts = process.split("-");
if (parts.length == 2) {
try {
proc = Integer.valueOf(parts[1]);
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Resolving proc name for 'event' " + proc);
}
} catch (Exception e) {
Log.e(TAG, "Cound not split process name " + process);
}
}
if (proc != 0) {
// search for the process in the task list
for (int psCount = 0; psCount < procInfos.size(); psCount++) {
int id = procInfos.get(psCount).pid;
if (id == proc) {
String processName = procInfos.get(psCount).processName;
details = processName;
String appName = "";
String[] pkgList = procInfos.get(count).pkgList;
for (int j = 0; j < pkgList.length; j++) {
if (details.length() > 0) {
details += ", ";
}
details += pkgList[j];
}
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Pattern 'event' resolved to " + details);
}
}
}
}
}
if (CommonLogSettings.DEBUG) {
Log.d(TAG, "Native Kernel wakelock parsed" + " name=" + name + " details=" + details + " count=" + count + " expire_count=" + expire_count + " wake_count=" + wake_count + " active_since=" + active_since + " total_time=" + total_time + " sleep_time=" + sleep_time + " max_time=" + max_time + "last_change=" + last_change + "ms_since_boot=" + msSinceBoot);
}
NativeKernelWakelock wl = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// on L sleep time is always 0 so use total time instead
wl = new NativeKernelWakelock(name, details, count, expire_count, wake_count, active_since, total_time, total_time, max_time, last_change, msSinceBoot);
} else {
wl = new NativeKernelWakelock(name, details, count, expire_count, wake_count, active_since, total_time, sleep_time, max_time, last_change, msSinceBoot);
}
myRet.add(wl);
} catch (Exception e) {
// go on
}
}
return myRet;
}
use of com.asksven.android.common.privateapiproxies.StatElement in project BetterBatteryStats by asksven.
the class OtherStatsDumpsys method getOtherStats.
/**
* Returns a list of alarm value objects
* @return
* @throws Exception
*/
public static ArrayList<StatElement> getOtherStats(boolean showWifi, boolean showBt) {
final String START_PATTERN = "Statistics since last charge";
final String STOP_PATTERN = "Statistics since last unplugged";
ArrayList<StatElement> myOther = null;
long nTotalCount = 0;
List<String> res = null;
boolean useRoot = false;
res = NonRootShell.getInstance().run("dumpsys batterystats");
if ((res != null) && (res.size() != 0)) {
if (res.contains("Permission Denial")) {
Pattern begin = Pattern.compile(START_PATTERN);
Pattern end = Pattern.compile(STOP_PATTERN);
boolean bParsing = false;
// we are looking for single line entries in the format
// Screen on: 29s 297ms (99.7%), Input events: 0, Active phone call: 0ms (0.0%)
// Screen brightnesses: dark 29s 297ms (100.0%)
// Signal levels: none 21s 595ms (73.5%) 0x, poor 4s 447ms (15.1%) 3x, moderate 3s 295ms (11.2%) 1x, good 36ms (0.1%) 1x
// Radio types: none 22s 610ms (77.0%) 0x, hsdpa 4s 635ms (15.8%) 2x, other 2s 128ms (7.2%) 1x
// Wifi on: 0ms (0.0%), Wifi running: 0ms (0.0%), Bluetooth on: 0ms (0.0%)
Pattern patternScreenOn = Pattern.compile("\\s\\sScreen on:\\s(.*) \\(.*\\sActive phone call:\\s(.*)\\s\\(.*");
Pattern patternWifiOn = Pattern.compile("\\s\\sWifi on:\\s(.*) \\(.*\\sWifi running:\\s(.*)\\s\\(.*\\sBluetooth on:\\s(.*)\\s\\(.*");
myOther = new ArrayList<StatElement>();
Misc myMisc = null;
// process the file
long total = 0;
for (int i = 0; i < res.size(); i++) {
// skip till start mark found
if (bParsing) {
// look for end
Matcher endMatcher = end.matcher(res.get(i));
if (endMatcher.find()) {
break;
}
// parse the alarms by block
String line = res.get(i);
Matcher screenOnMatcher = patternScreenOn.matcher(line);
Matcher wifiOnMatcher = patternWifiOn.matcher(line);
// screen on line
if (screenOnMatcher.find()) {
try {
long durationScreenOn = DateUtils.durationToLong(screenOnMatcher.group(1));
long durationInCall = DateUtils.durationToLong(screenOnMatcher.group(2));
myMisc = new Misc("Screen On", durationScreenOn, SystemClock.elapsedRealtime());
myOther.add(myMisc);
myMisc = new Misc("Phone On", durationInCall, SystemClock.elapsedRealtime());
myOther.add(myMisc);
Log.i(TAG, "Adding partial wakelock: " + myMisc.toString());
} catch (Exception e) {
Log.e(TAG, "Error: parsing error in package line (" + line + ")");
}
}
// phone on line
if (wifiOnMatcher.find()) {
try {
long durationWifiOn = DateUtils.durationToLong(wifiOnMatcher.group(1));
long durationWifiRunning = DateUtils.durationToLong(wifiOnMatcher.group(2));
long durationBtRunning = DateUtils.durationToLong(wifiOnMatcher.group(3));
if (showWifi) {
myMisc = new Misc("Wifi On", durationWifiOn, SystemClock.elapsedRealtime());
myOther.add(myMisc);
myMisc = new Misc("Wifi Running", durationWifiRunning, SystemClock.elapsedRealtime());
myOther.add(myMisc);
}
if (showBt) {
myMisc = new Misc("Bluetooth On", durationBtRunning, SystemClock.elapsedRealtime());
myOther.add(myMisc);
}
Log.i(TAG, "Adding partial wakelock: " + myMisc.toString());
} catch (Exception e) {
Log.e(TAG, "Error: parsing error in package line (" + line + ")");
}
}
} else {
// look for beginning
Matcher line = begin.matcher(res.get(i));
if (line.find()) {
bParsing = true;
}
}
}
// set the total
for (int i = 0; i < myOther.size(); i++) {
myOther.get(i).setTotal(total);
}
} else {
myOther = new ArrayList<StatElement>();
Misc myWl = new Misc(PERMISSION_DENIED, 1, 1);
myOther.add(myWl);
}
} else {
myOther = new ArrayList<StatElement>();
Misc myWl = new Misc(PERMISSION_DENIED, 1, 1);
myOther.add(myWl);
}
return myOther;
}
use of com.asksven.android.common.privateapiproxies.StatElement in project BetterBatteryStats by asksven.
the class UpdateTextWidgetService method onHandleWork.
@Override
protected void onHandleWork(Intent intent) {
// We have received work to do. The system or framework is already
// holding a wake lock for us at this point, so we can just go.
Log.i(TAG, "onHandleWork: " + intent);
if (LogSettings.DEBUG) {
Log.d(TAG, "Service started");
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
StatsProvider stats = StatsProvider.getInstance();
// make sure to flush cache
BatteryStatsProxy proxy = BatteryStatsProxy.getInstance(this);
if (proxy != null) {
proxy.invalidate();
}
if (allWidgetIds != null) {
if (allWidgetIds.length == 0) {
Log.i(TAG, "allWidgetIds was empty");
}
for (int widgetId : allWidgetIds) {
Log.i(TAG, "Update widget " + widgetId);
RemoteViews remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.widget);
final int cellSize = 40;
int width = 3;
int height = 2;
if (Build.VERSION.SDK_INT >= 16) {
Bundle widgetOptions = appWidgetManager.getAppWidgetOptions(widgetId);
width = AppWidget.sizeToCells(widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH) - 10);
height = AppWidget.sizeToCells(widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT) + 10);
Log.i(TAG, "[" + widgetId + "] height=" + height + " (" + widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT) + ")");
Log.i(TAG, "[" + widgetId + "] width=" + width + "(" + widgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH) + ")");
remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget_horz);
Log.i(TAG, "[" + widgetId + "] using horizontal layout");
remoteViews = new RemoteViews(this.getPackageName(), R.layout.text_widget_horz);
}
// we change the bg color of the layout based on alpha from prefs
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
int opacity = sharedPrefs.getInt("new_widget_bg_opacity", 20);
opacity = (255 * opacity) / 100;
remoteViews.setInt(R.id.background, "setBackgroundColor", (opacity << 24) & android.graphics.Color.BLACK);
long timeAwake = 0;
long timeSince = 0;
long timeScreenOn = 0;
long timeDeepSleep = 0;
long timePWL = 0;
long timeKWL = 0;
String refFrom = sharedPrefs.getString("new_widget_default_stat_type", Reference.UNPLUGGED_REF_FILENAME);
try {
// retrieve stats
Reference currentRef = StatsProvider.getInstance().getUncachedPartialReference(0);
Reference fromRef = ReferenceStore.getReferenceByName(refFrom, this);
remoteViews.setTextViewText(R.id.stat_type, fromRef.getLabel());
ArrayList<StatElement> otherStats = stats.getOtherUsageStatList(true, fromRef, false, true, currentRef);
if ((otherStats == null) || (otherStats.size() == 1)) {
// the desired stat type is unavailable, pick the alternate one and go on with that one
refFrom = sharedPrefs.getString("widget_fallback_stat_type", Reference.UNPLUGGED_REF_FILENAME);
fromRef = ReferenceStore.getReferenceByName(refFrom, this);
otherStats = stats.getOtherUsageStatList(true, fromRef, false, true, currentRef);
}
timeSince = StatsProvider.getInstance().getSince(fromRef, currentRef);
if ((otherStats != null) && (otherStats.size() > 1)) {
Misc timeAwakeStat = (Misc) stats.getElementByKey(otherStats, StatsProvider.LABEL_MISC_AWAKE);
if (timeAwakeStat != null) {
timeAwake = timeAwakeStat.getTimeOn();
} else {
timeAwake = 0;
}
Misc timeScreenOnStat = (Misc) stats.getElementByKey(otherStats, "Screen On");
if (timeScreenOnStat != null) {
timeScreenOn = timeScreenOnStat.getTimeOn();
} else {
timeScreenOn = 0;
}
Misc deepSleepStat = ((Misc) stats.getElementByKey(otherStats, "Deep Sleep"));
if (deepSleepStat != null) {
timeDeepSleep = deepSleepStat.getTimeOn();
} else {
timeDeepSleep = 0;
}
ArrayList<StatElement> pWakelockStats = stats.getWakelockStatList(true, fromRef, 0, 0, currentRef);
timePWL = stats.sum(pWakelockStats);
ArrayList<StatElement> kWakelockStats = stats.getKernelWakelockStatList(true, fromRef, 0, 0, currentRef);
timeKWL = stats.sum(kWakelockStats);
} else {
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + Log.getStackTraceString(e));
} finally {
if (LogSettings.DEBUG) {
Log.d(TAG, "Reference: " + refFrom);
Log.d(TAG, "Since: " + DateUtils.formatShort(timeSince) + " " + AppWidget.formatDuration(timeSince) + " " + timeSince);
Log.d(TAG, "Awake: " + DateUtils.formatShort(timeAwake) + " " + AppWidget.formatDuration(timeAwake) + " " + timeAwake);
Log.d(TAG, "Screen on: " + DateUtils.formatShort(timeScreenOn) + " " + AppWidget.formatDuration(timeScreenOn) + " " + timeScreenOn);
Log.d(TAG, "Deep sleep: " + DateUtils.formatShort(timeDeepSleep) + " " + AppWidget.formatDuration(timeDeepSleep) + " " + timeDeepSleep);
Log.d(TAG, "KWL: " + DateUtils.formatShort(timeKWL) + " " + AppWidget.formatDuration(timeKWL) + " " + timeKWL);
Log.d(TAG, "PWL: " + DateUtils.formatShort(timePWL) + " " + AppWidget.formatDuration(timePWL) + " " + timePWL);
}
remoteViews.setTextViewText(R.id.textViewSinceVal, AppWidget.formatDuration(timeSince));
// Show % depending on width and preferences
boolean show_pwc_only = sharedPrefs.getBoolean("widget_show_pct", false);
if (show_pwc_only) {
UpdateWidgetService.setValuesToPct(remoteViews, timeAwake, timeSince, timeScreenOn, timeDeepSleep, timePWL, timeKWL);
} else {
if (width <= 2) {
UpdateWidgetService.setValuesToDuration(remoteViews, timeAwake, timeSince, timeScreenOn, timeDeepSleep, timePWL, timeKWL);
} else {
UpdateWidgetService.setValuesToDurationAndPct(remoteViews, timeAwake, timeSince, timeScreenOn, timeDeepSleep, timePWL, timeKWL);
}
}
boolean showColor = sharedPrefs.getBoolean("text_widget_color", true);
UpdateWidgetService.setTextColor(remoteViews, showColor, this);
// tap zones
// Register an onClickListener for the graph -> refresh
Intent clickIntentRefresh = new Intent(this.getApplicationContext(), AppWidget.class);
clickIntentRefresh.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntentRefresh.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
PendingIntent pendingIntentRefresh = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntentRefresh, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.imageViewRefresh, pendingIntentRefresh);
// Register an onClickListener for the widget -> call main activity
Intent i = new Intent(Intent.ACTION_MAIN);
PackageManager manager = getPackageManager();
i = manager.getLaunchIntentForPackage(getPackageName());
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
int stat = Integer.valueOf(sharedPrefs.getString("widget_default_stat", "0"));
i.putExtra(StatsActivity.STAT, stat);
i.putExtra(StatsActivity.STAT_TYPE_FROM, refFrom);
i.putExtra(StatsActivity.STAT_TYPE_TO, Reference.CURRENT_REF_FILENAME);
PendingIntent clickPI = PendingIntent.getActivity(this.getApplicationContext(), PI_CODE, i, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.imageView1, clickPI);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
} else {
Log.i(TAG, "allWidgetIds was null");
}
Log.i(TAG, "Completed service @ " + DateUtils.formatDurationLong(SystemClock.elapsedRealtime()));
}
Aggregations