use of android.util.SparseArray in project KeepScore by nolanlawson.
the class GameDBHelper method findAllGameSummaries.
public List<GameSummary> findAllGameSummaries() {
synchronized (GameDBHelper.class) {
String[] columns = { "g." + COLUMN_ID, "g." + COLUMN_NAME, "g." + COLUMN_DATE_SAVED, // and put it into the proper order, since group_concat is always unordered in sqlite
"group_concat((ps.name || '" + GROUP_CONCAT_INNER_SEPARATOR + "' || ps.playerNumber), '" + GROUP_CONCAT_SEPARATOR + "')", // num rounds
"max(length(ps.history) - length(replace(ps.history, ',', '')) + 1)" };
String table = TABLE_GAMES + " g join " + TABLE_PLAYER_SCORES + " ps " + " on g." + COLUMN_ID + " = ps." + COLUMN_GAME_ID;
String groupBy = "g." + COLUMN_ID;
Cursor cursor = null;
try {
cursor = db.query(table, columns, null, null, groupBy, null, null);
List<GameSummary> result = new ArrayList<GameSummary>();
// re-use sparse array for performance
SparseArray<String> playerNumbersToNames = new SparseArray<String>();
while (cursor.moveToNext()) {
GameSummary gameSummary = new GameSummary();
gameSummary.setId(cursor.getInt(0));
gameSummary.setName(cursor.getString(1));
gameSummary.setDateSaved(cursor.getLong(2));
String playerNumbersAndNames = cursor.getString(3);
// sort by player number, get player names in order (no way to do this in sqlite, unfortunately)
playerNumbersToNames.clear();
for (String playerNumberAndName : StringUtil.split(playerNumbersAndNames, GROUP_CONCAT_SEPARATOR)) {
int idx = playerNumberAndName.indexOf(GROUP_CONCAT_INNER_SEPARATOR);
String playerName = playerNumberAndName.substring(0, idx);
int playerNumber = Integer.parseInt(playerNumberAndName.substring(idx + GROUP_CONCAT_INNER_SEPARATOR.length()));
playerNumbersToNames.put(playerNumber, playerName);
}
List<String> playerNames = new ArrayList<String>(playerNumbersToNames.size());
for (int i = 0, len = playerNumbersToNames.size(); i < len; i++) {
int playerNumber = playerNumbersToNames.keyAt(i);
playerNames.add(playerNumbersToNames.get(playerNumber));
}
gameSummary.setPlayerNames(playerNames);
gameSummary.setNumRounds(cursor.getInt(4));
result.add(gameSummary);
}
return result;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
use of android.util.SparseArray in project XobotOS by xamarin.
the class Parcel method readSparseArray.
/**
* Read and return a new SparseArray object from the parcel at the current
* dataPosition(). Returns null if the previously written list object was
* null. The given class loader will be used to load any enclosed
* Parcelables.
*/
public final SparseArray readSparseArray(ClassLoader loader) {
int N = readInt();
if (N < 0) {
return null;
}
SparseArray sa = new SparseArray(N);
readSparseArrayInternal(sa, N, loader);
return sa;
}
use of android.util.SparseArray in project android_frameworks_base by ResurrectionRemix.
the class BatteryStats method dumpCheckinLocked.
@SuppressWarnings("unused")
public void dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps, int flags, long histStart) {
prepareForDumpLocked();
dumpLine(pw, 0, /* uid */
"i", /* category */
VERSION_DATA, CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(), getEndPlatformVersion());
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
final boolean filtering = (flags & (DUMP_HISTORY_ONLY | DUMP_CHARGED_ONLY | DUMP_DAILY_ONLY)) != 0;
if ((flags & DUMP_INCLUDE_HISTORY) != 0 || (flags & DUMP_HISTORY_ONLY) != 0) {
if (startIteratingHistoryLocked()) {
try {
for (int i = 0; i < getHistoryStringPoolSize(); i++) {
pw.print(BATTERY_STATS_CHECKIN_VERSION);
pw.print(',');
pw.print(HISTORY_STRING_POOL);
pw.print(',');
pw.print(i);
pw.print(",");
pw.print(getHistoryTagPoolUid(i));
pw.print(",\"");
String str = getHistoryTagPoolString(i);
str = str.replace("\\", "\\\\");
str = str.replace("\"", "\\\"");
pw.print(str);
pw.print("\"");
pw.println();
}
dumpHistoryLocked(pw, flags, histStart, true);
} finally {
finishIteratingHistoryLocked();
}
}
}
if (filtering && (flags & (DUMP_CHARGED_ONLY | DUMP_DAILY_ONLY)) == 0) {
return;
}
if (apps != null) {
SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
for (int i = 0; i < apps.size(); i++) {
ApplicationInfo ai = apps.get(i);
Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(UserHandle.getAppId(ai.uid));
if (pkgs == null) {
pkgs = new Pair<>(new ArrayList<String>(), new MutableBoolean(false));
uids.put(UserHandle.getAppId(ai.uid), pkgs);
}
pkgs.first.add(ai.packageName);
}
SparseArray<? extends Uid> uidStats = getUidStats();
final int NU = uidStats.size();
String[] lineArgs = new String[2];
for (int i = 0; i < NU; i++) {
int uid = UserHandle.getAppId(uidStats.keyAt(i));
Pair<ArrayList<String>, MutableBoolean> pkgs = uids.get(uid);
if (pkgs != null && !pkgs.second.value) {
pkgs.second.value = true;
for (int j = 0; j < pkgs.first.size(); j++) {
lineArgs[0] = Integer.toString(uid);
lineArgs[1] = pkgs.first.get(j);
dumpLine(pw, 0, /* uid */
"i", /* category */
UID_DATA, (Object[]) lineArgs);
}
}
}
}
if (!filtering || (flags & DUMP_CHARGED_ONLY) != 0) {
dumpDurationSteps(pw, "", DISCHARGE_STEP_DATA, getDischargeLevelStepTracker(), true);
String[] lineArgs = new String[1];
long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
if (timeRemaining >= 0) {
lineArgs[0] = Long.toString(timeRemaining);
dumpLine(pw, 0, /* uid */
"i", /* category */
DISCHARGE_TIME_REMAIN_DATA, (Object[]) lineArgs);
}
dumpDurationSteps(pw, "", CHARGE_STEP_DATA, getChargeLevelStepTracker(), true);
timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
if (timeRemaining >= 0) {
lineArgs[0] = Long.toString(timeRemaining);
dumpLine(pw, 0, /* uid */
"i", /* category */
CHARGE_TIME_REMAIN_DATA, (Object[]) lineArgs);
}
dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1, (flags & DUMP_DEVICE_WIFI_ONLY) != 0);
}
}
use of android.util.SparseArray in project android_frameworks_base by ResurrectionRemix.
the class MessageUtils method findMessageNames.
/**
* Finds the names of integer constants. Searches the specified {@code classes}, looking for
* accessible static integer fields whose names begin with one of the specified {@prefixes}.
*
* @param classes the classes to examine.
* @prefixes only consider fields names starting with one of these prefixes.
* @return a {@link SparseArray} mapping integer constants to their names.
*/
public static SparseArray<String> findMessageNames(Class[] classes, String[] prefixes) {
SparseArray<String> messageNames = new SparseArray<>();
for (Class c : classes) {
String className = c.getName();
if (DBG)
Log.d(TAG, "Examining class " + className);
Field[] fields;
try {
fields = c.getDeclaredFields();
} catch (SecurityException e) {
Log.e(TAG, "Can't list fields of class " + className);
continue;
}
for (Field field : fields) {
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) | !Modifier.isFinal(modifiers)) {
continue;
}
String name = field.getName();
for (String prefix : prefixes) {
// Does this look like a constant?
if (!name.startsWith(prefix)) {
continue;
}
try {
// TODO: can we have the caller try to access the field instead, so we don't
// expose constants it does not have access to?
field.setAccessible(true);
// Fetch the constant's value.
int value;
try {
value = field.getInt(null);
} catch (IllegalArgumentException | ExceptionInInitializerError e) {
// Either way, give up on this field.
break;
}
// Check for duplicate values.
String previousName = messageNames.get(value);
if (previousName != null && !previousName.equals(name)) {
throw new DuplicateConstantError(name, previousName, value);
}
messageNames.put(value, name);
if (DBG) {
Log.d(TAG, String.format("Found constant: %s.%s = %d", className, name, value));
}
} catch (SecurityException | IllegalAccessException e) {
// Not allowed to make the field accessible, or no access. Ignore.
continue;
}
}
}
}
return messageNames;
}
use of android.util.SparseArray in project android_frameworks_base by ResurrectionRemix.
the class AppErrors method appNotResponding.
final void appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation) {
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
if (mService.mController != null) {
try {
// 0 == continue, -1 = kill process immediately
int res = mService.mController.appEarlyNotResponding(app.processName, app.pid, annotation);
if (res < 0 && app.pid != MY_PID) {
app.kill("anr", true);
}
} catch (RemoteException e) {
mService.mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
long anrTime = SystemClock.uptimeMillis();
if (ActivityManagerService.MONITOR_CPU_USAGE) {
mService.updateCpuStatsNow();
}
// Unless configured otherwise, swallow ANRs in background processes & kill the process.
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
boolean isSilentANR;
synchronized (mService) {
// PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
if (mService.mShuttingDown) {
Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
return;
} else if (app.notResponding) {
Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
return;
} else if (app.crashing) {
Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
return;
}
// In case we come through here for the same app before completing
// this one, mark as anring now so we will bail out.
app.notResponding = true;
// Log the ANR to the event log.
EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, app.processName, app.info.flags, annotation);
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(app.pid);
// Don't dump other PIDs if it's a background ANR
isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID;
if (!isSilentANR) {
int parentPid = app.pid;
if (parent != null && parent.app != null && parent.app.pid > 0) {
parentPid = parent.app.pid;
}
if (parentPid != app.pid)
firstPids.add(parentPid);
if (MY_PID != app.pid && MY_PID != parentPid)
firstPids.add(MY_PID);
for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
ProcessRecord r = mService.mLruProcesses.get(i);
if (r != null && r.thread != null) {
int pid = r.pid;
if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
if (r.persistent) {
firstPids.add(pid);
if (DEBUG_ANR)
Slog.i(TAG, "Adding persistent proc: " + r);
} else {
lastPids.put(pid, Boolean.TRUE);
if (DEBUG_ANR)
Slog.i(TAG, "Adding ANR proc: " + r);
}
}
}
}
}
}
// Log the ANR to the main log.
StringBuilder info = new StringBuilder();
info.setLength(0);
info.append("ANR in ").append(app.processName);
if (activity != null && activity.shortComponentName != null) {
info.append(" (").append(activity.shortComponentName).append(")");
}
info.append("\n");
info.append("PID: ").append(app.pid).append("\n");
if (annotation != null) {
info.append("Reason: ").append(annotation).append("\n");
}
if (parent != null && parent != activity) {
info.append("Parent: ").append(parent.shortComponentName).append("\n");
}
ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
String[] nativeProcs = NATIVE_STACKS_OF_INTEREST;
// don't dump native PIDs for background ANRs
File tracesFile = null;
if (isSilentANR) {
tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids, null);
} else {
tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, nativeProcs);
}
String cpuInfo = null;
if (ActivityManagerService.MONITOR_CPU_USAGE) {
mService.updateCpuStatsNow();
synchronized (mService.mProcessCpuTracker) {
cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
}
info.append(processCpuTracker.printCurrentLoad());
info.append(cpuInfo);
}
info.append(processCpuTracker.printCurrentState(anrTime));
Slog.e(TAG, info.toString());
if (tracesFile == null) {
// There is no trace file, so dump (only) the alleged culprit's threads to the log
Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
}
mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, cpuInfo, tracesFile, null);
if (mService.mController != null) {
try {
// 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
int res = mService.mController.appNotResponding(app.processName, app.pid, info.toString());
if (res != 0) {
if (res < 0 && app.pid != MY_PID) {
app.kill("anr", true);
} else {
synchronized (mService) {
mService.mServices.scheduleServiceTimeoutLocked(app);
}
}
return;
}
} catch (RemoteException e) {
mService.mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
synchronized (mService) {
mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
if (isSilentANR) {
app.kill("bg anr", true);
return;
}
// Set the app's notResponding state, and look up the errorReportReceiver
makeAppNotRespondingLocked(app, activity != null ? activity.shortComponentName : null, annotation != null ? "ANR " + annotation : "ANR", info.toString());
boolean enableTraceRename = SystemProperties.getBoolean("persist.sys.enableTraceRename", false);
//Set the trace file name to app name + current date format to avoid overrinding trace file based on debug flag
if (enableTraceRename) {
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
if (tracesPath != null && tracesPath.length() != 0) {
File traceRenameFile = new File(tracesPath);
String newTracesPath;
int lpos = tracesPath.lastIndexOf(".");
if (-1 != lpos)
newTracesPath = tracesPath.substring(0, lpos) + "_" + app.processName + "_" + mTraceDateFormat.format(new Date()) + tracesPath.substring(lpos);
else
newTracesPath = tracesPath + "_" + app.processName;
traceRenameFile.renameTo(new File(newTracesPath));
SystemClock.sleep(1000);
}
}
// Bring up the infamous App Not Responding dialog
Message msg = Message.obtain();
HashMap<String, Object> map = new HashMap<String, Object>();
msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
msg.obj = map;
msg.arg1 = aboveSystem ? 1 : 0;
map.put("app", app);
if (activity != null) {
map.put("activity", activity);
}
mService.mUiHandler.sendMessage(msg);
}
}
Aggregations