1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 20 import java.util.ArrayList; 21 22 /** 23 * Collects performance data between two function calls in Bundle objects and 24 * outputs the results using writer of type {@link PerformanceResultsWriter}. 25 * <p> 26 * {@link #beginSnapshot(String)} and {@link #endSnapshot()} functions collect 27 * memory usage information and measure runtime between calls to begin and end. 28 * These functions logically wrap around an entire test, and should be called 29 * with name of test as the label, e.g. EmailPerformanceTest. 30 * <p> 31 * {@link #startTiming(String)} and {@link #stopTiming(String)} functions 32 * measure runtime between calls to start and stop. These functions logically 33 * wrap around a single test case or a small block of code, and should be called 34 * with the name of test case as the label, e.g. testSimpleSendMailSequence. 35 * <p> 36 * {@link #addIteration(String)} inserts intermediate measurement point which 37 * can be labeled with a String, e.g. Launch email app, compose, send, etc. 38 * <p> 39 * Snapshot and timing functions do not interfere with each other, and thus can 40 * be called in any order. The intended structure is to wrap begin/endSnapshot 41 * around calls to start/stopTiming, for example: 42 * <p> 43 * <code>beginSnapshot("EmailPerformanceTest"); 44 * startTiming("testSimpleSendSequence"); 45 * addIteration("Launch email app"); 46 * addIteration("Compose"); 47 * stopTiming("Send"); 48 * startTiming("testComplexSendSequence"); 49 * stopTiming(""); 50 * startTiming("testAddLabel"); 51 * stopTiming(""); 52 * endSnapshot();</code> 53 * <p> 54 * Structure of results output is up to implementor of 55 * {@link PerformanceResultsWriter }. 56 * 57 * {@hide} Pending approval for public API. 58 */ 59 public class PerformanceCollector { 60 61 /** 62 * Interface for reporting performance data. 63 */ 64 public interface PerformanceResultsWriter { 65 66 /** 67 * Callback invoked as first action in 68 * PerformanceCollector#beginSnapshot(String) for reporting the start of 69 * a performance snapshot. 70 * 71 * @param label description of code block between beginSnapshot and 72 * PerformanceCollector#endSnapshot() 73 * @see PerformanceCollector#beginSnapshot(String) 74 */ 75 public void writeBeginSnapshot(String label); 76 77 /** 78 * Callback invoked as last action in PerformanceCollector#endSnapshot() 79 * for reporting performance data collected in the snapshot. 80 * 81 * @param results memory and runtime metrics stored as key/value pairs, 82 * in the same structure as returned by 83 * PerformanceCollector#endSnapshot() 84 * @see PerformanceCollector#endSnapshot() 85 */ 86 public void writeEndSnapshot(Bundle results); 87 88 /** 89 * Callback invoked as first action in 90 * PerformanceCollector#startTiming(String) for reporting the start of 91 * a timing measurement. 92 * 93 * @param label description of code block between startTiming and 94 * PerformanceCollector#stopTiming(String) 95 * @see PerformanceCollector#startTiming(String) 96 */ 97 public void writeStartTiming(String label); 98 99 /** 100 * Callback invoked as last action in 101 * {@link PerformanceCollector#stopTiming(String)} for reporting the 102 * sequence of timings measured. 103 * 104 * @param results runtime metrics of code block between calls to 105 * startTiming and stopTiming, in the same structure as 106 * returned by PerformanceCollector#stopTiming(String) 107 * @see PerformanceCollector#stopTiming(String) 108 */ 109 public void writeStopTiming(Bundle results); 110 111 /** 112 * Callback invoked as last action in 113 * {@link PerformanceCollector#addMeasurement(String, long)} for 114 * reporting an integer type measurement. 115 * 116 * @param label short description of the metric that was measured 117 * @param value long value of the measurement 118 */ 119 public void writeMeasurement(String label, long value); 120 121 /** 122 * Callback invoked as last action in 123 * {@link PerformanceCollector#addMeasurement(String, float)} for 124 * reporting a float type measurement. 125 * 126 * @param label short description of the metric that was measured 127 * @param value float value of the measurement 128 */ 129 public void writeMeasurement(String label, float value); 130 131 /** 132 * Callback invoked as last action in 133 * {@link PerformanceCollector#addMeasurement(String, String)} for 134 * reporting a string field. 135 * 136 * @param label short description of the metric that was measured 137 * @param value string summary of the measurement 138 */ 139 public void writeMeasurement(String label, String value); 140 } 141 142 /** 143 * In a results Bundle, this key references a List of iteration Bundles. 144 */ 145 public static final String METRIC_KEY_ITERATIONS = "iterations"; 146 /** 147 * In an iteration Bundle, this key describes the iteration. 148 */ 149 public static final String METRIC_KEY_LABEL = "label"; 150 /** 151 * In a results Bundle, this key reports the cpu time of the code block 152 * under measurement. 153 */ 154 public static final String METRIC_KEY_CPU_TIME = "cpu_time"; 155 /** 156 * In a results Bundle, this key reports the execution time of the code 157 * block under measurement. 158 */ 159 public static final String METRIC_KEY_EXECUTION_TIME = "execution_time"; 160 /** 161 * In a snapshot Bundle, this key reports the number of received 162 * transactions from the binder driver before collection started. 163 */ 164 public static final String METRIC_KEY_PRE_RECEIVED_TRANSACTIONS = "pre_received_transactions"; 165 /** 166 * In a snapshot Bundle, this key reports the number of transactions sent by 167 * the running program before collection started. 168 */ 169 public static final String METRIC_KEY_PRE_SENT_TRANSACTIONS = "pre_sent_transactions"; 170 /** 171 * In a snapshot Bundle, this key reports the number of received 172 * transactions from the binder driver. 173 */ 174 public static final String METRIC_KEY_RECEIVED_TRANSACTIONS = "received_transactions"; 175 /** 176 * In a snapshot Bundle, this key reports the number of transactions sent by 177 * the running program. 178 */ 179 public static final String METRIC_KEY_SENT_TRANSACTIONS = "sent_transactions"; 180 /** 181 * In a snapshot Bundle, this key reports the number of garbage collection 182 * invocations. 183 */ 184 public static final String METRIC_KEY_GC_INVOCATION_COUNT = "gc_invocation_count"; 185 /** 186 * In a snapshot Bundle, this key reports the amount of allocated memory 187 * used by the running program. 188 */ 189 public static final String METRIC_KEY_JAVA_ALLOCATED = "java_allocated"; 190 /** 191 * In a snapshot Bundle, this key reports the amount of free memory 192 * available to the running program. 193 */ 194 public static final String METRIC_KEY_JAVA_FREE = "java_free"; 195 /** 196 * In a snapshot Bundle, this key reports the number of private dirty pages 197 * used by dalvik. 198 */ 199 public static final String METRIC_KEY_JAVA_PRIVATE_DIRTY = "java_private_dirty"; 200 /** 201 * In a snapshot Bundle, this key reports the proportional set size for 202 * dalvik. 203 */ 204 public static final String METRIC_KEY_JAVA_PSS = "java_pss"; 205 /** 206 * In a snapshot Bundle, this key reports the number of shared dirty pages 207 * used by dalvik. 208 */ 209 public static final String METRIC_KEY_JAVA_SHARED_DIRTY = "java_shared_dirty"; 210 /** 211 * In a snapshot Bundle, this key reports the total amount of memory 212 * available to the running program. 213 */ 214 public static final String METRIC_KEY_JAVA_SIZE = "java_size"; 215 /** 216 * In a snapshot Bundle, this key reports the amount of allocated memory in 217 * the native heap. 218 */ 219 public static final String METRIC_KEY_NATIVE_ALLOCATED = "native_allocated"; 220 /** 221 * In a snapshot Bundle, this key reports the amount of free memory in the 222 * native heap. 223 */ 224 public static final String METRIC_KEY_NATIVE_FREE = "native_free"; 225 /** 226 * In a snapshot Bundle, this key reports the number of private dirty pages 227 * used by the native heap. 228 */ 229 public static final String METRIC_KEY_NATIVE_PRIVATE_DIRTY = "native_private_dirty"; 230 /** 231 * In a snapshot Bundle, this key reports the proportional set size for the 232 * native heap. 233 */ 234 public static final String METRIC_KEY_NATIVE_PSS = "native_pss"; 235 /** 236 * In a snapshot Bundle, this key reports the number of shared dirty pages 237 * used by the native heap. 238 */ 239 public static final String METRIC_KEY_NATIVE_SHARED_DIRTY = "native_shared_dirty"; 240 /** 241 * In a snapshot Bundle, this key reports the size of the native heap. 242 */ 243 public static final String METRIC_KEY_NATIVE_SIZE = "native_size"; 244 /** 245 * In a snapshot Bundle, this key reports the number of objects allocated 246 * globally. 247 */ 248 public static final String METRIC_KEY_GLOBAL_ALLOC_COUNT = "global_alloc_count"; 249 /** 250 * In a snapshot Bundle, this key reports the size of all objects allocated 251 * globally. 252 */ 253 public static final String METRIC_KEY_GLOBAL_ALLOC_SIZE = "global_alloc_size"; 254 /** 255 * In a snapshot Bundle, this key reports the number of objects freed 256 * globally. 257 */ 258 public static final String METRIC_KEY_GLOBAL_FREED_COUNT = "global_freed_count"; 259 /** 260 * In a snapshot Bundle, this key reports the size of all objects freed 261 * globally. 262 */ 263 public static final String METRIC_KEY_GLOBAL_FREED_SIZE = "global_freed_size"; 264 /** 265 * In a snapshot Bundle, this key reports the number of private dirty pages 266 * used by everything else. 267 */ 268 public static final String METRIC_KEY_OTHER_PRIVATE_DIRTY = "other_private_dirty"; 269 /** 270 * In a snapshot Bundle, this key reports the proportional set size for 271 * everything else. 272 */ 273 public static final String METRIC_KEY_OTHER_PSS = "other_pss"; 274 /** 275 * In a snapshot Bundle, this key reports the number of shared dirty pages 276 * used by everything else. 277 */ 278 public static final String METRIC_KEY_OTHER_SHARED_DIRTY = "other_shared_dirty"; 279 280 private PerformanceResultsWriter mPerfWriter; 281 private Bundle mPerfSnapshot; 282 private Bundle mPerfMeasurement; 283 private long mSnapshotCpuTime; 284 private long mSnapshotExecTime; 285 private long mCpuTime; 286 private long mExecTime; 287 288 public PerformanceCollector() { 289 } 290 291 public PerformanceCollector(PerformanceResultsWriter writer) { 292 setPerformanceResultsWriter(writer); 293 } 294 295 public void setPerformanceResultsWriter(PerformanceResultsWriter writer) { 296 mPerfWriter = writer; 297 } 298 299 /** 300 * Begin collection of memory usage information. 301 * 302 * @param label description of code block between beginSnapshot and 303 * endSnapshot, used to label output 304 */ 305 public void beginSnapshot(String label) { 306 if (mPerfWriter != null) 307 mPerfWriter.writeBeginSnapshot(label); 308 startPerformanceSnapshot(); 309 } 310 311 /** 312 * End collection of memory usage information. Returns collected data in a 313 * Bundle object. 314 * 315 * @return Memory and runtime metrics stored as key/value pairs. Values are 316 * of type long, and keys include: 317 * <ul> 318 * <li>{@link #METRIC_KEY_CPU_TIME cpu_time} 319 * <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time} 320 * <li>{@link #METRIC_KEY_PRE_RECEIVED_TRANSACTIONS 321 * pre_received_transactions} 322 * <li>{@link #METRIC_KEY_PRE_SENT_TRANSACTIONS 323 * pre_sent_transactions} 324 * <li>{@link #METRIC_KEY_RECEIVED_TRANSACTIONS 325 * received_transactions} 326 * <li>{@link #METRIC_KEY_SENT_TRANSACTIONS sent_transactions} 327 * <li>{@link #METRIC_KEY_GC_INVOCATION_COUNT gc_invocation_count} 328 * <li>{@link #METRIC_KEY_JAVA_ALLOCATED java_allocated} 329 * <li>{@link #METRIC_KEY_JAVA_FREE java_free} 330 * <li>{@link #METRIC_KEY_JAVA_PRIVATE_DIRTY java_private_dirty} 331 * <li>{@link #METRIC_KEY_JAVA_PSS java_pss} 332 * <li>{@link #METRIC_KEY_JAVA_SHARED_DIRTY java_shared_dirty} 333 * <li>{@link #METRIC_KEY_JAVA_SIZE java_size} 334 * <li>{@link #METRIC_KEY_NATIVE_ALLOCATED native_allocated} 335 * <li>{@link #METRIC_KEY_NATIVE_FREE native_free} 336 * <li>{@link #METRIC_KEY_NATIVE_PRIVATE_DIRTY native_private_dirty} 337 * <li>{@link #METRIC_KEY_NATIVE_PSS native_pss} 338 * <li>{@link #METRIC_KEY_NATIVE_SHARED_DIRTY native_shared_dirty} 339 * <li>{@link #METRIC_KEY_NATIVE_SIZE native_size} 340 * <li>{@link #METRIC_KEY_GLOBAL_ALLOC_COUNT global_alloc_count} 341 * <li>{@link #METRIC_KEY_GLOBAL_ALLOC_SIZE global_alloc_size} 342 * <li>{@link #METRIC_KEY_GLOBAL_FREED_COUNT global_freed_count} 343 * <li>{@link #METRIC_KEY_GLOBAL_FREED_SIZE global_freed_size} 344 * <li>{@link #METRIC_KEY_OTHER_PRIVATE_DIRTY other_private_dirty} 345 * <li>{@link #METRIC_KEY_OTHER_PSS other_pss} 346 * <li>{@link #METRIC_KEY_OTHER_SHARED_DIRTY other_shared_dirty} 347 * </ul> 348 */ 349 public Bundle endSnapshot() { 350 endPerformanceSnapshot(); 351 if (mPerfWriter != null) 352 mPerfWriter.writeEndSnapshot(mPerfSnapshot); 353 return mPerfSnapshot; 354 } 355 356 /** 357 * Start measurement of user and cpu time. 358 * 359 * @param label description of code block between startTiming and 360 * stopTiming, used to label output 361 */ 362 public void startTiming(String label) { 363 if (mPerfWriter != null) 364 mPerfWriter.writeStartTiming(label); 365 mPerfMeasurement = new Bundle(); 366 mPerfMeasurement.putParcelableArrayList( 367 METRIC_KEY_ITERATIONS, new ArrayList<Parcelable>()); 368 mExecTime = SystemClock.uptimeMillis(); 369 mCpuTime = Process.getElapsedCpuTime(); 370 } 371 372 /** 373 * Add a measured segment, and start measuring the next segment. Returns 374 * collected data in a Bundle object. 375 * 376 * @param label description of code block between startTiming and 377 * addIteration, and between two calls to addIteration, used 378 * to label output 379 * @return Runtime metrics stored as key/value pairs. Values are of type 380 * long, and keys include: 381 * <ul> 382 * <li>{@link #METRIC_KEY_LABEL label} 383 * <li>{@link #METRIC_KEY_CPU_TIME cpu_time} 384 * <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time} 385 * </ul> 386 */ 387 public Bundle addIteration(String label) { 388 mCpuTime = Process.getElapsedCpuTime() - mCpuTime; 389 mExecTime = SystemClock.uptimeMillis() - mExecTime; 390 391 Bundle iteration = new Bundle(); 392 iteration.putString(METRIC_KEY_LABEL, label); 393 iteration.putLong(METRIC_KEY_EXECUTION_TIME, mExecTime); 394 iteration.putLong(METRIC_KEY_CPU_TIME, mCpuTime); 395 mPerfMeasurement.getParcelableArrayList(METRIC_KEY_ITERATIONS).add(iteration); 396 397 mExecTime = SystemClock.uptimeMillis(); 398 mCpuTime = Process.getElapsedCpuTime(); 399 return iteration; 400 } 401 402 /** 403 * Stop measurement of user and cpu time. 404 * 405 * @param label description of code block between addIteration or 406 * startTiming and stopTiming, used to label output 407 * @return Runtime metrics stored in a bundle, including all iterations 408 * between calls to startTiming and stopTiming. List of iterations 409 * is keyed by {@link #METRIC_KEY_ITERATIONS iterations}. 410 */ 411 public Bundle stopTiming(String label) { 412 addIteration(label); 413 if (mPerfWriter != null) 414 mPerfWriter.writeStopTiming(mPerfMeasurement); 415 return mPerfMeasurement; 416 } 417 418 /** 419 * Add an integer type measurement to the collector. 420 * 421 * @param label short description of the metric that was measured 422 * @param value long value of the measurement 423 */ 424 public void addMeasurement(String label, long value) { 425 if (mPerfWriter != null) 426 mPerfWriter.writeMeasurement(label, value); 427 } 428 429 /** 430 * Add a float type measurement to the collector. 431 * 432 * @param label short description of the metric that was measured 433 * @param value float value of the measurement 434 */ 435 public void addMeasurement(String label, float value) { 436 if (mPerfWriter != null) 437 mPerfWriter.writeMeasurement(label, value); 438 } 439 440 /** 441 * Add a string field to the collector. 442 * 443 * @param label short description of the metric that was measured 444 * @param value string summary of the measurement 445 */ 446 public void addMeasurement(String label, String value) { 447 if (mPerfWriter != null) 448 mPerfWriter.writeMeasurement(label, value); 449 } 450 451 /* 452 * Starts tracking memory usage, binder transactions, and real & cpu timing. 453 */ 454 private void startPerformanceSnapshot() { 455 // Create new snapshot 456 mPerfSnapshot = new Bundle(); 457 458 // Add initial binder counts 459 Bundle binderCounts = getBinderCounts(); 460 for (String key : binderCounts.keySet()) { 461 mPerfSnapshot.putLong("pre_" + key, binderCounts.getLong(key)); 462 } 463 464 // Force a GC and zero out the performance counters. Do this 465 // before reading initial CPU/wall-clock times so we don't include 466 // the cost of this setup in our final metrics. 467 startAllocCounting(); 468 469 // Record CPU time up to this point, and start timing. Note: this 470 // must happen at the end of this method, otherwise the timing will 471 // include noise. 472 mSnapshotExecTime = SystemClock.uptimeMillis(); 473 mSnapshotCpuTime = Process.getElapsedCpuTime(); 474 } 475 476 /* 477 * Stops tracking memory usage, binder transactions, and real & cpu timing. 478 * Stores collected data as type long into Bundle object for reporting. 479 */ 480 private void endPerformanceSnapshot() { 481 // Stop the timing. This must be done first before any other counting is 482 // stopped. 483 mSnapshotCpuTime = Process.getElapsedCpuTime() - mSnapshotCpuTime; 484 mSnapshotExecTime = SystemClock.uptimeMillis() - mSnapshotExecTime; 485 486 stopAllocCounting(); 487 488 long nativeMax = Debug.getNativeHeapSize() / 1024; 489 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 490 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 491 492 Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); 493 Debug.getMemoryInfo(memInfo); 494 495 Runtime runtime = Runtime.getRuntime(); 496 497 long dalvikMax = runtime.totalMemory() / 1024; 498 long dalvikFree = runtime.freeMemory() / 1024; 499 long dalvikAllocated = dalvikMax - dalvikFree; 500 501 // Add final binder counts 502 Bundle binderCounts = getBinderCounts(); 503 for (String key : binderCounts.keySet()) { 504 mPerfSnapshot.putLong(key, binderCounts.getLong(key)); 505 } 506 507 // Add alloc counts 508 Bundle allocCounts = getAllocCounts(); 509 for (String key : allocCounts.keySet()) { 510 mPerfSnapshot.putLong(key, allocCounts.getLong(key)); 511 } 512 513 mPerfSnapshot.putLong(METRIC_KEY_EXECUTION_TIME, mSnapshotExecTime); 514 mPerfSnapshot.putLong(METRIC_KEY_CPU_TIME, mSnapshotCpuTime); 515 516 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax); 517 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated); 518 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree); 519 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PSS, memInfo.nativePss); 520 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PRIVATE_DIRTY, memInfo.nativePrivateDirty); 521 mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SHARED_DIRTY, memInfo.nativeSharedDirty); 522 523 mPerfSnapshot.putLong(METRIC_KEY_JAVA_SIZE, dalvikMax); 524 mPerfSnapshot.putLong(METRIC_KEY_JAVA_ALLOCATED, dalvikAllocated); 525 mPerfSnapshot.putLong(METRIC_KEY_JAVA_FREE, dalvikFree); 526 mPerfSnapshot.putLong(METRIC_KEY_JAVA_PSS, memInfo.dalvikPss); 527 mPerfSnapshot.putLong(METRIC_KEY_JAVA_PRIVATE_DIRTY, memInfo.dalvikPrivateDirty); 528 mPerfSnapshot.putLong(METRIC_KEY_JAVA_SHARED_DIRTY, memInfo.dalvikSharedDirty); 529 530 mPerfSnapshot.putLong(METRIC_KEY_OTHER_PSS, memInfo.otherPss); 531 mPerfSnapshot.putLong(METRIC_KEY_OTHER_PRIVATE_DIRTY, memInfo.otherPrivateDirty); 532 mPerfSnapshot.putLong(METRIC_KEY_OTHER_SHARED_DIRTY, memInfo.otherSharedDirty); 533 } 534 535 /* 536 * Starts allocation counting. This triggers a gc and resets the counts. 537 */ 538 private static void startAllocCounting() { 539 // Before we start trigger a GC and reset the debug counts. Run the 540 // finalizers and another GC before starting and stopping the alloc 541 // counts. This will free up any objects that were just sitting around 542 // waiting for their finalizers to be run. 543 Runtime.getRuntime().gc(); 544 Runtime.getRuntime().runFinalization(); 545 Runtime.getRuntime().gc(); 546 547 Debug.resetAllCounts(); 548 549 // start the counts 550 Debug.startAllocCounting(); 551 } 552 553 /* 554 * Stops allocation counting. 555 */ 556 private static void stopAllocCounting() { 557 Runtime.getRuntime().gc(); 558 Runtime.getRuntime().runFinalization(); 559 Runtime.getRuntime().gc(); 560 Debug.stopAllocCounting(); 561 } 562 563 /* 564 * Returns a bundle with the current results from the allocation counting. 565 */ 566 private static Bundle getAllocCounts() { 567 Bundle results = new Bundle(); 568 results.putLong(METRIC_KEY_GLOBAL_ALLOC_COUNT, Debug.getGlobalAllocCount()); 569 results.putLong(METRIC_KEY_GLOBAL_ALLOC_SIZE, Debug.getGlobalAllocSize()); 570 results.putLong(METRIC_KEY_GLOBAL_FREED_COUNT, Debug.getGlobalFreedCount()); 571 results.putLong(METRIC_KEY_GLOBAL_FREED_SIZE, Debug.getGlobalFreedSize()); 572 results.putLong(METRIC_KEY_GC_INVOCATION_COUNT, Debug.getGlobalGcInvocationCount()); 573 return results; 574 } 575 576 /* 577 * Returns a bundle with the counts for various binder counts for this 578 * process. Currently the only two that are reported are the number of send 579 * and the number of received transactions. 580 */ 581 private static Bundle getBinderCounts() { 582 Bundle results = new Bundle(); 583 results.putLong(METRIC_KEY_SENT_TRANSACTIONS, Debug.getBinderSentTransactions()); 584 results.putLong(METRIC_KEY_RECEIVED_TRANSACTIONS, Debug.getBinderReceivedTransactions()); 585 return results; 586 } 587 } 588