Loading services/core/java/com/android/server/notification/NotificationManagerService.java +80 −17 Original line number Diff line number Diff line Loading @@ -112,6 +112,9 @@ import com.android.server.statusbar.StatusBarManagerInternal; import libcore.io.IoUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -1663,7 +1666,12 @@ public class NotificationManagerService extends SystemService { return; } dumpImpl(pw, DumpFilter.parseFromArguments(args)); final DumpFilter filter = DumpFilter.parseFromArguments(args); if (filter != null && filter.stats) { dumpJson(pw, filter); } else { dumpImpl(pw, filter); } } @Override Loading Loading @@ -1799,6 +1807,32 @@ public class NotificationManagerService extends SystemService { return "callState"; } return null; }; private void dumpJson(PrintWriter pw, DumpFilter filter) { JSONObject dump = new JSONObject(); try { dump.put("service", "Notification Manager"); JSONArray bans = new JSONArray(); try { ArrayMap<Integer, ArrayList<String>> packageBans = getPackageBans(filter); for (Integer userId : packageBans.keySet()) { for (String packageName : packageBans.get(userId)) { JSONObject ban = new JSONObject(); ban.put("userId", userId); ban.put("packageName", packageName); bans.put(ban); } } } catch (NameNotFoundException e) { // pass } dump.put("bans", bans); dump.put("stats", mUsageStats.dumpJson(filter)); } catch (JSONException e) { e.printStackTrace(); } pw.println(dump); } void dumpImpl(PrintWriter pw, DumpFilter filter) { Loading Loading @@ -1920,24 +1954,42 @@ public class NotificationManagerService extends SystemService { try { pw.println("\n Banned Packages:"); ArrayMap<Integer, ArrayList<String>> packageBans = getPackageBans(filter); for (Integer userId : packageBans.keySet()) { for (String packageName : packageBans.get(userId)) { pw.println(" " + userId + ": " + packageName); } } } catch (NameNotFoundException e) { // pass } } } private ArrayMap<Integer, ArrayList<String>> getPackageBans(DumpFilter filter) throws NameNotFoundException { ArrayMap<Integer, ArrayList<String>> packageBans = new ArrayMap<>(); ArrayList<String> packageNames = new ArrayList<>(); for (UserInfo user : UserManager.get(getContext()).getUsers()) { final int userId = user.getUserHandle().getIdentifier(); pw.println(" UserId " + userId); final PackageManager packageManager = getContext().getPackageManager(); List<PackageInfo> packages = packageManager.getInstalledPackages(0, userId); final int packageCount = packages.size(); for (int p = 0; p < packageCount; p++) { final String packageName = packages.get(p).packageName; if (filter == null || filter.matches(packageName)) { final int uid = packageManager.getPackageUid(packageName, userId); if (!checkNotificationOp(packageName, uid)) { pw.println(" " + packageName); packageNames.add(packageName); } } } } catch (NameNotFoundException e) { // pass if (!packageNames.isEmpty()) { packageBans.put(userId, packageNames); packageNames = new ArrayList<>(); } } return packageBans; } /** Loading Loading @@ -3449,6 +3501,9 @@ public class NotificationManagerService extends SystemService { public static final class DumpFilter { public String pkgFilter; public boolean zen; public long since; public boolean stats; private boolean all; public static DumpFilter parseFromArguments(String[] args) { if (args != null && args.length == 2 && "p".equals(args[0]) Loading @@ -3460,27 +3515,35 @@ public class NotificationManagerService extends SystemService { if (args != null && args.length == 1 && "zen".equals(args[0])) { final DumpFilter filter = new DumpFilter(); filter.zen = true; filter.all = true; return filter; } if (args != null && args.length >= 1 && "--stats".equals(args[0])) { final DumpFilter filter = new DumpFilter(); filter.stats = true; filter.since = args.length == 2 ? Long.valueOf(args[1]) : 0; filter.all = true; return filter; } return null; } public boolean matches(StatusBarNotification sbn) { return zen ? true : sbn != null return all ? true : sbn != null && (matches(sbn.getPackageName()) || matches(sbn.getOpPkg())); } public boolean matches(ComponentName component) { return zen ? true : component != null && matches(component.getPackageName()); return all ? true : component != null && matches(component.getPackageName()); } public boolean matches(String pkg) { return zen ? true : pkg != null && pkg.toLowerCase().contains(pkgFilter); return all ? true : pkg != null && pkg.toLowerCase().contains(pkgFilter); } @Override public String toString() { return zen ? "zen" : ('\'' + pkgFilter + '\''); return stats ? "stats" : zen ? "zen" : ('\'' + pkgFilter + '\''); } } Loading services/core/java/com/android/server/notification/NotificationUsageStats.java +131 −4 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; Loading @@ -32,8 +31,14 @@ import android.util.Log; import com.android.internal.logging.MetricsLogger; import com.android.server.notification.NotificationManagerService.DumpFilter; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; Loading Loading @@ -220,6 +225,31 @@ public class NotificationUsageStats { return result; } public synchronized JSONObject dumpJson(DumpFilter filter) { JSONObject dump = new JSONObject(); if (ENABLE_AGGREGATED_IN_MEMORY_STATS) { try { JSONArray aggregatedStats = new JSONArray(); for (AggregatedStats as : mStats.values()) { if (filter != null && !filter.matches(as.key)) continue; aggregatedStats.put(as.dumpJson()); } dump.put("current", aggregatedStats); } catch (JSONException e) { // pass } } if (ENABLE_SQLITE_LOG) { try { dump.put("historical", mSQLiteLog.dumpJson(filter)); } catch (JSONException e) { // pass } } return dump; } public synchronized void dump(PrintWriter pw, String indent, DumpFilter filter) { if (ENABLE_AGGREGATED_IN_MEMORY_STATS) { for (AggregatedStats as : mStats.values()) { Loading Loading @@ -250,6 +280,7 @@ public class NotificationUsageStats { private final Context mContext; public final String key; private final long mCreated; private AggregatedStats mPrevious; // ---- Updated as the respective events occur. Loading Loading @@ -285,6 +316,7 @@ public class NotificationUsageStats { public AggregatedStats(Context context, String key) { this.key = key; mContext = context; mCreated = SystemClock.elapsedRealtime(); } public void countApiUse(NotificationRecord record) { Loading Loading @@ -450,6 +482,47 @@ public class NotificationUsageStats { indent + " numBlocked=" + numBlocked + ",\n" + indent + "}"; } public JSONObject dumpJson() throws JSONException { JSONObject dump = new JSONObject(); dump.put("key", key); dump.put("duration", SystemClock.elapsedRealtime() - mCreated); maybePut(dump, "numPostedByApp", numPostedByApp); maybePut(dump, "numUpdatedByApp", numUpdatedByApp); maybePut(dump, "numRemovedByApp", numRemovedByApp); maybePut(dump, "numPeopleCacheHit", numPeopleCacheHit); maybePut(dump, "numPeopleCacheMiss", numPeopleCacheMiss); maybePut(dump, "numWithStaredPeople", numWithStaredPeople); maybePut(dump, "numWithValidPeople", numWithValidPeople); maybePut(dump, "numBlocked", numBlocked); maybePut(dump, "numWithActions", numWithActions); maybePut(dump, "numPrivate", numPrivate); maybePut(dump, "numSecret", numSecret); maybePut(dump, "numPriorityMax", numPriorityMax); maybePut(dump, "numPriorityHigh", numPriorityHigh); maybePut(dump, "numPriorityLow", numPriorityLow); maybePut(dump, "numPriorityMin", numPriorityMin); maybePut(dump, "numInterrupt", numInterrupt); maybePut(dump, "numWithBigText", numWithBigText); maybePut(dump, "numWithBigPicture", numWithBigPicture); maybePut(dump, "numForegroundService", numForegroundService); maybePut(dump, "numOngoing", numOngoing); maybePut(dump, "numAutoCancel", numAutoCancel); maybePut(dump, "numWithLargeIcon", numWithLargeIcon); maybePut(dump, "numWithInbox", numWithInbox); maybePut(dump, "numWithMediaSession", numWithMediaSession); maybePut(dump, "numWithTitle", numWithTitle); maybePut(dump, "numWithText", numWithText); maybePut(dump, "numWithSubText", numWithSubText); maybePut(dump, "numWithInfoText", numWithInfoText); return dump; } private void maybePut(JSONObject dump, String name, int value) throws JSONException { if (value > 0) { dump.put(name, value); } } } /** Loading Loading @@ -780,14 +853,51 @@ public class NotificationUsageStats { mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification)); } private JSONArray JsonPostFrequencies(DumpFilter filter) throws JSONException { JSONArray frequencies = new JSONArray(); SQLiteDatabase db = mHelper.getReadableDatabase(); long midnight = getMidnightMs(); String q = "SELECT " + COL_EVENT_USER_ID + ", " + COL_PKG + ", " + // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)' "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + "AS day, " + "COUNT(*) AS cnt " + "FROM " + TAB_LOG + " " + "WHERE " + COL_EVENT_TYPE + "=" + EVENT_TYPE_POST + " AND " + COL_EVENT_TIME + " > " + filter.since + " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG; Cursor cursor = db.rawQuery(q, null); try { for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { int userId = cursor.getInt(0); String pkg = cursor.getString(1); if (filter != null && !filter.matches(pkg)) continue; int day = cursor.getInt(2); int count = cursor.getInt(3); JSONObject row = new JSONObject(); row.put("user_id", userId); row.put("package", pkg); row.put("day", day); row.put("count", count); frequencies.put(row); } } finally { cursor.close(); } return frequencies; } public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) { SQLiteDatabase db = mHelper.getReadableDatabase(); long nowMs = System.currentTimeMillis(); long midnight = getMidnightMs(); String q = "SELECT " + COL_EVENT_USER_ID + ", " + COL_PKG + ", " + // Bucket by day by looking at 'floor((nowMs - eventTimeMs) / dayMs)' "CAST(((" + nowMs + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)' "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + "AS day, " + "COUNT(*) AS cnt " + "FROM " + TAB_LOG + " " + Loading @@ -810,6 +920,13 @@ public class NotificationUsageStats { } } private long getMidnightMs() { GregorianCalendar midnight = new GregorianCalendar(); midnight.set(midnight.get(Calendar.YEAR), midnight.get(Calendar.MONTH), midnight.get(Calendar.DATE), 23, 59, 59); return midnight.getTimeInMillis(); } private void writeEvent(long eventTimeMs, int eventType, NotificationRecord r) { ContentValues cv = new ContentValues(); cv.put(COL_EVENT_USER_ID, r.sbn.getUser().getIdentifier()); Loading Loading @@ -874,5 +991,15 @@ public class NotificationUsageStats { public void dump(PrintWriter pw, String indent, DumpFilter filter) { printPostFrequencies(pw, indent, filter); } public JSONObject dumpJson(DumpFilter filter) { JSONObject dump = new JSONObject(); try { dump.put("post_frequency", JsonPostFrequencies(filter)); } catch (JSONException e) { // pass } return dump; } } } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +80 −17 Original line number Diff line number Diff line Loading @@ -112,6 +112,9 @@ import com.android.server.statusbar.StatusBarManagerInternal; import libcore.io.IoUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -1663,7 +1666,12 @@ public class NotificationManagerService extends SystemService { return; } dumpImpl(pw, DumpFilter.parseFromArguments(args)); final DumpFilter filter = DumpFilter.parseFromArguments(args); if (filter != null && filter.stats) { dumpJson(pw, filter); } else { dumpImpl(pw, filter); } } @Override Loading Loading @@ -1799,6 +1807,32 @@ public class NotificationManagerService extends SystemService { return "callState"; } return null; }; private void dumpJson(PrintWriter pw, DumpFilter filter) { JSONObject dump = new JSONObject(); try { dump.put("service", "Notification Manager"); JSONArray bans = new JSONArray(); try { ArrayMap<Integer, ArrayList<String>> packageBans = getPackageBans(filter); for (Integer userId : packageBans.keySet()) { for (String packageName : packageBans.get(userId)) { JSONObject ban = new JSONObject(); ban.put("userId", userId); ban.put("packageName", packageName); bans.put(ban); } } } catch (NameNotFoundException e) { // pass } dump.put("bans", bans); dump.put("stats", mUsageStats.dumpJson(filter)); } catch (JSONException e) { e.printStackTrace(); } pw.println(dump); } void dumpImpl(PrintWriter pw, DumpFilter filter) { Loading Loading @@ -1920,24 +1954,42 @@ public class NotificationManagerService extends SystemService { try { pw.println("\n Banned Packages:"); ArrayMap<Integer, ArrayList<String>> packageBans = getPackageBans(filter); for (Integer userId : packageBans.keySet()) { for (String packageName : packageBans.get(userId)) { pw.println(" " + userId + ": " + packageName); } } } catch (NameNotFoundException e) { // pass } } } private ArrayMap<Integer, ArrayList<String>> getPackageBans(DumpFilter filter) throws NameNotFoundException { ArrayMap<Integer, ArrayList<String>> packageBans = new ArrayMap<>(); ArrayList<String> packageNames = new ArrayList<>(); for (UserInfo user : UserManager.get(getContext()).getUsers()) { final int userId = user.getUserHandle().getIdentifier(); pw.println(" UserId " + userId); final PackageManager packageManager = getContext().getPackageManager(); List<PackageInfo> packages = packageManager.getInstalledPackages(0, userId); final int packageCount = packages.size(); for (int p = 0; p < packageCount; p++) { final String packageName = packages.get(p).packageName; if (filter == null || filter.matches(packageName)) { final int uid = packageManager.getPackageUid(packageName, userId); if (!checkNotificationOp(packageName, uid)) { pw.println(" " + packageName); packageNames.add(packageName); } } } } catch (NameNotFoundException e) { // pass if (!packageNames.isEmpty()) { packageBans.put(userId, packageNames); packageNames = new ArrayList<>(); } } return packageBans; } /** Loading Loading @@ -3449,6 +3501,9 @@ public class NotificationManagerService extends SystemService { public static final class DumpFilter { public String pkgFilter; public boolean zen; public long since; public boolean stats; private boolean all; public static DumpFilter parseFromArguments(String[] args) { if (args != null && args.length == 2 && "p".equals(args[0]) Loading @@ -3460,27 +3515,35 @@ public class NotificationManagerService extends SystemService { if (args != null && args.length == 1 && "zen".equals(args[0])) { final DumpFilter filter = new DumpFilter(); filter.zen = true; filter.all = true; return filter; } if (args != null && args.length >= 1 && "--stats".equals(args[0])) { final DumpFilter filter = new DumpFilter(); filter.stats = true; filter.since = args.length == 2 ? Long.valueOf(args[1]) : 0; filter.all = true; return filter; } return null; } public boolean matches(StatusBarNotification sbn) { return zen ? true : sbn != null return all ? true : sbn != null && (matches(sbn.getPackageName()) || matches(sbn.getOpPkg())); } public boolean matches(ComponentName component) { return zen ? true : component != null && matches(component.getPackageName()); return all ? true : component != null && matches(component.getPackageName()); } public boolean matches(String pkg) { return zen ? true : pkg != null && pkg.toLowerCase().contains(pkgFilter); return all ? true : pkg != null && pkg.toLowerCase().contains(pkgFilter); } @Override public String toString() { return zen ? "zen" : ('\'' + pkgFilter + '\''); return stats ? "stats" : zen ? "zen" : ('\'' + pkgFilter + '\''); } } Loading
services/core/java/com/android/server/notification/NotificationUsageStats.java +131 −4 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; Loading @@ -32,8 +31,14 @@ import android.util.Log; import com.android.internal.logging.MetricsLogger; import com.android.server.notification.NotificationManagerService.DumpFilter; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; Loading Loading @@ -220,6 +225,31 @@ public class NotificationUsageStats { return result; } public synchronized JSONObject dumpJson(DumpFilter filter) { JSONObject dump = new JSONObject(); if (ENABLE_AGGREGATED_IN_MEMORY_STATS) { try { JSONArray aggregatedStats = new JSONArray(); for (AggregatedStats as : mStats.values()) { if (filter != null && !filter.matches(as.key)) continue; aggregatedStats.put(as.dumpJson()); } dump.put("current", aggregatedStats); } catch (JSONException e) { // pass } } if (ENABLE_SQLITE_LOG) { try { dump.put("historical", mSQLiteLog.dumpJson(filter)); } catch (JSONException e) { // pass } } return dump; } public synchronized void dump(PrintWriter pw, String indent, DumpFilter filter) { if (ENABLE_AGGREGATED_IN_MEMORY_STATS) { for (AggregatedStats as : mStats.values()) { Loading Loading @@ -250,6 +280,7 @@ public class NotificationUsageStats { private final Context mContext; public final String key; private final long mCreated; private AggregatedStats mPrevious; // ---- Updated as the respective events occur. Loading Loading @@ -285,6 +316,7 @@ public class NotificationUsageStats { public AggregatedStats(Context context, String key) { this.key = key; mContext = context; mCreated = SystemClock.elapsedRealtime(); } public void countApiUse(NotificationRecord record) { Loading Loading @@ -450,6 +482,47 @@ public class NotificationUsageStats { indent + " numBlocked=" + numBlocked + ",\n" + indent + "}"; } public JSONObject dumpJson() throws JSONException { JSONObject dump = new JSONObject(); dump.put("key", key); dump.put("duration", SystemClock.elapsedRealtime() - mCreated); maybePut(dump, "numPostedByApp", numPostedByApp); maybePut(dump, "numUpdatedByApp", numUpdatedByApp); maybePut(dump, "numRemovedByApp", numRemovedByApp); maybePut(dump, "numPeopleCacheHit", numPeopleCacheHit); maybePut(dump, "numPeopleCacheMiss", numPeopleCacheMiss); maybePut(dump, "numWithStaredPeople", numWithStaredPeople); maybePut(dump, "numWithValidPeople", numWithValidPeople); maybePut(dump, "numBlocked", numBlocked); maybePut(dump, "numWithActions", numWithActions); maybePut(dump, "numPrivate", numPrivate); maybePut(dump, "numSecret", numSecret); maybePut(dump, "numPriorityMax", numPriorityMax); maybePut(dump, "numPriorityHigh", numPriorityHigh); maybePut(dump, "numPriorityLow", numPriorityLow); maybePut(dump, "numPriorityMin", numPriorityMin); maybePut(dump, "numInterrupt", numInterrupt); maybePut(dump, "numWithBigText", numWithBigText); maybePut(dump, "numWithBigPicture", numWithBigPicture); maybePut(dump, "numForegroundService", numForegroundService); maybePut(dump, "numOngoing", numOngoing); maybePut(dump, "numAutoCancel", numAutoCancel); maybePut(dump, "numWithLargeIcon", numWithLargeIcon); maybePut(dump, "numWithInbox", numWithInbox); maybePut(dump, "numWithMediaSession", numWithMediaSession); maybePut(dump, "numWithTitle", numWithTitle); maybePut(dump, "numWithText", numWithText); maybePut(dump, "numWithSubText", numWithSubText); maybePut(dump, "numWithInfoText", numWithInfoText); return dump; } private void maybePut(JSONObject dump, String name, int value) throws JSONException { if (value > 0) { dump.put(name, value); } } } /** Loading Loading @@ -780,14 +853,51 @@ public class NotificationUsageStats { mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification)); } private JSONArray JsonPostFrequencies(DumpFilter filter) throws JSONException { JSONArray frequencies = new JSONArray(); SQLiteDatabase db = mHelper.getReadableDatabase(); long midnight = getMidnightMs(); String q = "SELECT " + COL_EVENT_USER_ID + ", " + COL_PKG + ", " + // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)' "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + "AS day, " + "COUNT(*) AS cnt " + "FROM " + TAB_LOG + " " + "WHERE " + COL_EVENT_TYPE + "=" + EVENT_TYPE_POST + " AND " + COL_EVENT_TIME + " > " + filter.since + " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG; Cursor cursor = db.rawQuery(q, null); try { for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { int userId = cursor.getInt(0); String pkg = cursor.getString(1); if (filter != null && !filter.matches(pkg)) continue; int day = cursor.getInt(2); int count = cursor.getInt(3); JSONObject row = new JSONObject(); row.put("user_id", userId); row.put("package", pkg); row.put("day", day); row.put("count", count); frequencies.put(row); } } finally { cursor.close(); } return frequencies; } public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) { SQLiteDatabase db = mHelper.getReadableDatabase(); long nowMs = System.currentTimeMillis(); long midnight = getMidnightMs(); String q = "SELECT " + COL_EVENT_USER_ID + ", " + COL_PKG + ", " + // Bucket by day by looking at 'floor((nowMs - eventTimeMs) / dayMs)' "CAST(((" + nowMs + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)' "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " + "AS day, " + "COUNT(*) AS cnt " + "FROM " + TAB_LOG + " " + Loading @@ -810,6 +920,13 @@ public class NotificationUsageStats { } } private long getMidnightMs() { GregorianCalendar midnight = new GregorianCalendar(); midnight.set(midnight.get(Calendar.YEAR), midnight.get(Calendar.MONTH), midnight.get(Calendar.DATE), 23, 59, 59); return midnight.getTimeInMillis(); } private void writeEvent(long eventTimeMs, int eventType, NotificationRecord r) { ContentValues cv = new ContentValues(); cv.put(COL_EVENT_USER_ID, r.sbn.getUser().getIdentifier()); Loading Loading @@ -874,5 +991,15 @@ public class NotificationUsageStats { public void dump(PrintWriter pw, String indent, DumpFilter filter) { printPostFrequencies(pw, indent, filter); } public JSONObject dumpJson(DumpFilter filter) { JSONObject dump = new JSONObject(); try { dump.put("post_frequency", JsonPostFrequencies(filter)); } catch (JSONException e) { // pass } return dump; } } }