1 /* 2 * Copyright (C) 2011 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 com.android.frameworkperf; 18 19 import java.io.File; 20 import java.io.FileNotFoundException; 21 import java.io.FileOutputStream; 22 import java.io.IOException; 23 import java.io.RandomAccessFile; 24 25 import org.xmlpull.v1.XmlPullParser; 26 import org.xmlpull.v1.XmlPullParserException; 27 28 import android.app.Service; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.pm.PackageManager; 32 import android.content.res.TypedArray; 33 import android.content.res.XmlResourceParser; 34 import android.graphics.Bitmap; 35 import android.graphics.BitmapFactory; 36 import android.graphics.Paint; 37 import android.os.Bundle; 38 import android.os.FileUtils; 39 import android.os.Handler; 40 import android.os.IBinder; 41 import android.os.Looper; 42 import android.os.Message; 43 import android.os.Messenger; 44 import android.os.Process; 45 import android.os.RemoteException; 46 import android.os.SystemClock; 47 import android.util.AttributeSet; 48 import android.util.DisplayMetrics; 49 import android.util.Log; 50 import android.util.Xml; 51 import android.view.LayoutInflater; 52 53 public class TestService extends Service { 54 static final String TAG = "Perf"; 55 56 final static Op[] mOpPairs = new Op[] { 57 new MethodCallOp(), new NoOp(), 58 new MethodCallOp(), new CpuOp(), 59 new MethodCallOp(), new SchedulerOp(), 60 new MethodCallOp(), new GcOp(), 61 new MethodCallOp(), new CreateFileOp(), 62 new MethodCallOp(), new CreateWriteFileOp(), 63 new MethodCallOp(), new CreateWriteSyncFileOp(), 64 new MethodCallOp(), new WriteFileOp(), 65 new MethodCallOp(), new ReadFileOp(), 66 new SchedulerOp(), new SchedulerOp(), 67 new GcOp(), new NoOp(), 68 new ObjectGcOp(), new NoOp(), 69 new FinalizingGcOp(), new NoOp(), 70 new PaintGcOp(), new NoOp(), 71 new IpcOp(), new NoOp(), 72 new IpcOp(), new CpuOp(), 73 new IpcOp(), new SchedulerOp(), 74 new IpcOp(), new GcOp(), 75 new IpcOp(), new CreateFileOp(), 76 new IpcOp(), new CreateWriteFileOp(), 77 new IpcOp(), new CreateWriteSyncFileOp(), 78 new IpcOp(), new WriteFileOp(), 79 new IpcOp(), new ReadFileOp(), 80 new CreateFileOp(), new NoOp(), 81 new CreateWriteFileOp(), new NoOp(), 82 new CreateWriteSyncFileOp(), new NoOp(), 83 new WriteFileOp(), new NoOp(), 84 new ReadFileOp(), new NoOp(), 85 new WriteFileOp(), new CreateWriteFileOp(), 86 new ReadFileOp(), new CreateWriteFileOp(), 87 new WriteFileOp(), new CreateWriteSyncFileOp(), 88 new ReadFileOp(), new CreateWriteSyncFileOp(), 89 new WriteFileOp(), new WriteFileOp(), 90 new WriteFileOp(), new ReadFileOp(), 91 new ReadFileOp(), new WriteFileOp(), 92 new ReadFileOp(), new ReadFileOp(), 93 new OpenXmlResOp(), new NoOp(), 94 new ReadXmlAttrsOp(), new NoOp(), 95 new ParseXmlResOp(), new NoOp(), 96 new ParseLargeXmlResOp(), new NoOp(), 97 new LayoutInflaterOp(), new NoOp(), 98 new LayoutInflaterLargeOp(), new NoOp(), 99 new LayoutInflaterViewOp(), new NoOp(), 100 new LayoutInflaterButtonOp(), new NoOp(), 101 new LayoutInflaterImageButtonOp(), new NoOp(), 102 new CreateBitmapOp(), new NoOp(), 103 new CreateRecycleBitmapOp(), new NoOp(), 104 new LoadSmallBitmapOp(), new NoOp(), 105 new LoadRecycleSmallBitmapOp(), new NoOp(), 106 new LoadLargeBitmapOp(), new NoOp(), 107 new LoadRecycleLargeBitmapOp(), new NoOp(), 108 new LoadSmallScaledBitmapOp(), new NoOp(), 109 new LoadLargeScaledBitmapOp(), new NoOp(), 110 }; 111 112 final static Op[] mAvailOps = new Op[] { 113 null, 114 new NoOp(), 115 new CpuOp(), 116 new SchedulerOp(), 117 new MethodCallOp(), 118 new GcOp(), 119 new ObjectGcOp(), 120 new FinalizingGcOp(), 121 new PaintGcOp(), 122 new IpcOp(), 123 new CreateFileOp(), 124 new CreateWriteFileOp(), 125 new CreateWriteSyncFileOp(), 126 new WriteFileOp(), 127 new ReadFileOp(), 128 new OpenXmlResOp(), 129 new ReadXmlAttrsOp(), 130 new ParseXmlResOp(), 131 new ParseLargeXmlResOp(), 132 new LayoutInflaterOp(), 133 new LayoutInflaterLargeOp(), 134 new LayoutInflaterViewOp(), 135 new LayoutInflaterButtonOp(), 136 new LayoutInflaterImageButtonOp(), 137 new CreateBitmapOp(), 138 new CreateRecycleBitmapOp(), 139 new LoadSmallBitmapOp(), 140 new LoadRecycleSmallBitmapOp(), 141 new LoadLargeBitmapOp(), 142 new LoadRecycleLargeBitmapOp(), 143 new LoadSmallScaledBitmapOp(), 144 new LoadLargeScaledBitmapOp(), 145 }; 146 147 static final int CMD_START_TEST = 1; 148 static final int CMD_TERMINATE = 2; 149 150 static final int MSG_REALLY_START = 1000; 151 static final int MSG_REALLY_TERMINATE = 1001; 152 153 static final int RES_TEST_FINISHED = 1; 154 static final int RES_TERMINATED = 2; 155 156 final Handler mHandler = new Handler() { 157 @Override public void handleMessage(Message msg) { 158 switch (msg.what) { 159 case CMD_START_TEST: { 160 // Give a little time for things to settle down. 161 Message newMsg = Message.obtain(null, MSG_REALLY_START); 162 newMsg.obj = msg.obj; 163 newMsg.replyTo = msg.replyTo; 164 sendMessageDelayed(newMsg, 500); 165 } break; 166 case MSG_REALLY_START: { 167 Bundle bundle = (Bundle)msg.obj; 168 bundle.setClassLoader(getClassLoader()); 169 final TestArgs args = (TestArgs)bundle.getParcelable("args"); 170 final Messenger replyTo = msg.replyTo; 171 mRunner.run(this, args, new Runnable() { 172 @Override public void run() { 173 if (replyTo != null) { 174 Message msg = Message.obtain(null, RES_TEST_FINISHED); 175 Bundle bundle = new Bundle(); 176 bundle.putParcelable("res", new RunResult(mRunner)); 177 msg.obj = bundle; 178 try { 179 replyTo.send(msg); 180 } catch (RemoteException e) { 181 } 182 } 183 } 184 }); 185 } break; 186 case CMD_TERMINATE: { 187 // Give a little time for things to settle down. 188 Message newMsg = Message.obtain(null, MSG_REALLY_TERMINATE); 189 newMsg.obj = msg.obj; 190 newMsg.replyTo = msg.replyTo; 191 sendMessageDelayed(newMsg, 50); 192 } break; 193 case MSG_REALLY_TERMINATE: { 194 if (msg.replyTo != null) { 195 Message reply = Message.obtain(null, RES_TERMINATED); 196 try { 197 msg.replyTo.send(reply); 198 } catch (RemoteException e) { 199 } 200 } 201 terminate(); 202 } break; 203 } 204 } 205 }; 206 207 final TestRunner mRunner = new TestRunner(); 208 209 @Override 210 public IBinder onBind(Intent intent) { 211 return (new Messenger(mHandler)).getBinder(); 212 } 213 214 void terminate() { 215 Runtime.getRuntime().exit(0); 216 } 217 218 enum BackgroundMode { 219 NOTHING, 220 CPU, 221 SCHEDULER 222 }; 223 224 public class TestRunner { 225 Handler mHandler; 226 long mMaxRunTime; 227 long mMaxOps; 228 Op mForegroundOp; 229 Op mBackgroundOp; 230 Runnable mDoneCallback; 231 232 RunnerThread mBackgroundThread; 233 RunnerThread mForegroundThread; 234 long mStartTime; 235 236 boolean mBackgroundRunning; 237 boolean mForegroundRunning; 238 239 long mBackgroundEndTime; 240 long mBackgroundOps; 241 long mForegroundEndTime; 242 long mForegroundOps; 243 244 public TestRunner() { 245 } 246 247 public String getForegroundName() { 248 return mForegroundOp.getName(); 249 } 250 251 public String getBackgroundName() { 252 return mBackgroundOp.getName(); 253 } 254 255 public String getName() { 256 String fgName = mForegroundOp.getName(); 257 String bgName = mBackgroundOp.getName(); 258 StringBuilder res = new StringBuilder(); 259 if (fgName != null) { 260 res.append(fgName); 261 res.append("Fg"); 262 } 263 if (bgName != null) { 264 res.append(bgName); 265 res.append("Bg"); 266 } 267 return res.toString(); 268 } 269 270 public String getForegroundLongName() { 271 return mForegroundOp.getLongName(); 272 } 273 274 public String getBackgroundLongName() { 275 return mBackgroundOp.getLongName(); 276 } 277 278 public void run(Handler handler, TestArgs args, Runnable doneCallback) { 279 mHandler = handler; 280 mMaxRunTime = args.maxTime; 281 mMaxOps = args.maxOps; 282 if (args.combOp >= 0) { 283 mForegroundOp = mOpPairs[args.combOp]; 284 mBackgroundOp = mOpPairs[args.combOp+1]; 285 } else { 286 mForegroundOp = mAvailOps[args.fgOp]; 287 mBackgroundOp = mAvailOps[args.bgOp]; 288 } 289 mDoneCallback = doneCallback; 290 mBackgroundThread = new RunnerThread("background", new Runnable() { 291 @Override public void run() { 292 boolean running; 293 int ops = 0; 294 do { 295 running = mBackgroundOp.onRun(); 296 ops++; 297 } while (evalRepeat(running, true) && running); 298 mBackgroundEndTime = SystemClock.uptimeMillis(); 299 mBackgroundOps = ops * mBackgroundOp.getOpsPerRun(); 300 threadFinished(false); 301 } 302 }, Process.THREAD_PRIORITY_BACKGROUND); 303 mForegroundThread = new RunnerThread("background", new Runnable() { 304 @Override public void run() { 305 boolean running; 306 int ops = 0; 307 do { 308 running = mForegroundOp.onRun(); 309 ops++; 310 } while (evalRepeat(true, running) && running); 311 mForegroundEndTime = SystemClock.uptimeMillis(); 312 mForegroundOps = ops * mForegroundOp.getOpsPerRun(); 313 threadFinished(true); 314 } 315 }, Process.THREAD_PRIORITY_FOREGROUND); 316 317 mForegroundOp.onInit(TestService.this, true); 318 mBackgroundOp.onInit(TestService.this, false); 319 320 synchronized (this) { 321 mStartTime = SystemClock.uptimeMillis(); 322 mBackgroundRunning = true; 323 mForegroundRunning = true; 324 } 325 326 mBackgroundThread.start(); 327 mForegroundThread.start(); 328 } 329 330 public long getForegroundTime() { 331 return mForegroundEndTime-mStartTime; 332 } 333 334 public long getForegroundOps() { 335 return mForegroundOps; 336 } 337 338 public long getBackgroundTime() { 339 return mBackgroundEndTime-mStartTime; 340 } 341 342 public long getBackgroundOps() { 343 return mBackgroundOps; 344 } 345 346 private boolean evalRepeat(boolean bgRunning, boolean fgRunning) { 347 synchronized (this) { 348 if (!bgRunning) { 349 mBackgroundRunning = false; 350 } 351 if (!fgRunning) { 352 mForegroundRunning = false; 353 } 354 if (!mBackgroundRunning && !mForegroundRunning) { 355 return false; 356 } 357 if (mMaxOps > 0) { 358 // iteration-limited case 359 if (mForegroundOps >= mMaxOps) { 360 return false; 361 } 362 mForegroundOps++; 363 } else { 364 // time-limited case 365 long now = SystemClock.uptimeMillis(); 366 if (now > (mStartTime+mMaxRunTime)) { 367 return false; 368 } 369 } 370 return true; 371 } 372 } 373 374 private void threadFinished(boolean foreground) { 375 synchronized (this) { 376 if (foreground) { 377 mForegroundRunning = false; 378 } else { 379 mBackgroundRunning = false; 380 } 381 if (!mBackgroundRunning && !mForegroundRunning) { 382 mHandler.post(new Runnable() { 383 @Override public void run() { 384 mForegroundOp.onTerm(TestService.this); 385 mBackgroundOp.onTerm(TestService.this); 386 if (mDoneCallback != null) { 387 mDoneCallback.run(); 388 } 389 } 390 }); 391 } 392 } 393 } 394 } 395 396 class RunnerThread extends Thread { 397 private final Runnable mOp; 398 private final int mPriority; 399 400 RunnerThread(String name, Runnable op, int priority) { 401 super(name); 402 mOp = op; 403 mPriority = priority; 404 } 405 406 public void run() { 407 Process.setThreadPriority(mPriority); 408 mOp.run(); 409 } 410 } 411 412 static public abstract class Op { 413 final String mName; 414 final String mLongName; 415 416 public Op(String name, String longName) { 417 mName = name; 418 mLongName = longName; 419 } 420 421 public String getName() { 422 return mName; 423 } 424 425 public String getLongName() { 426 return mLongName; 427 } 428 429 void onInit(Context context, boolean foreground) { 430 } 431 432 abstract boolean onRun(); 433 434 void onTerm(Context context) { 435 } 436 437 int getOpsPerRun() { 438 return 1; 439 } 440 } 441 442 static class NoOp extends Op { 443 NoOp() { 444 super(null, "Nothing"); 445 } 446 447 boolean onRun() { 448 return false; 449 } 450 451 int getOpsPerRun() { 452 return 0; 453 } 454 } 455 456 static class CpuOp extends Op { 457 CpuOp() { 458 super("CPU", "Consume CPU"); 459 } 460 461 boolean onRun() { 462 return true; 463 } 464 } 465 466 static class SchedulerOp extends Op { 467 SchedulerOp() { 468 super("Sched", "Change scheduler group"); 469 } 470 471 boolean onRun() { 472 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 473 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 474 return true; 475 } 476 } 477 478 static class GcOp extends Op { 479 GcOp() { 480 super("Gc", "Run garbage collector"); 481 } 482 483 boolean onRun() { 484 byte[] stuff = new byte[1024*1024]; 485 return true; 486 } 487 } 488 489 static class ObjectGcOp extends Op { 490 ObjectGcOp() { 491 super("ObjectGc", "Run garbage collector with simple objects"); 492 } 493 494 boolean onRun() { 495 Object obj = new Object(); 496 return true; 497 } 498 } 499 500 static class FinalizingGcOp extends Op { 501 class Finalizable { 502 Finalizable() {} 503 @Override 504 protected void finalize() throws Throwable { 505 super.finalize(); 506 } 507 } 508 509 FinalizingGcOp() { 510 super("FinalizingGc", "Run garbage collector with finalizable objects"); 511 } 512 513 boolean onRun() { 514 Finalizable obj = new Finalizable(); 515 return true; 516 } 517 } 518 519 static class PaintGcOp extends Op { 520 PaintGcOp() { 521 super("PaintGc", "Run garbage collector with Paint objects"); 522 } 523 524 boolean onRun() { 525 Paint p = new Paint(); 526 return true; 527 } 528 } 529 530 static class MethodCallOp extends Op { 531 MethodCallOp() { 532 super("MethodCall", "Method call"); 533 } 534 535 boolean onRun() { 536 final int N = getOpsPerRun(); 537 for (int i=0; i<N; i++) { 538 someFunc(i); 539 } 540 return true; 541 } 542 543 int someFunc(int foo) { 544 return 0; 545 } 546 547 int getOpsPerRun() { 548 return 500; 549 } 550 } 551 552 static class IpcOp extends Op { 553 PackageManager mPm; 554 String mProcessName; 555 556 IpcOp() { 557 super("Ipc", "IPC to system process"); 558 } 559 560 void onInit(Context context, boolean foreground) { 561 mPm = context.getPackageManager(); 562 mProcessName = context.getApplicationInfo().processName; 563 } 564 565 boolean onRun() { 566 final int N = getOpsPerRun(); 567 for (int i=0; i<N; i++) { 568 mPm.queryContentProviders(mProcessName, Process.myUid(), 0); 569 } 570 return true; 571 } 572 573 int getOpsPerRun() { 574 return 100; 575 } 576 } 577 578 static class OpenXmlResOp extends Op { 579 Context mContext; 580 581 OpenXmlResOp() { 582 super("OpenXmlRes", "Open (and close) an XML resource"); 583 } 584 585 void onInit(Context context, boolean foreground) { 586 mContext = context; 587 } 588 589 boolean onRun() { 590 XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple); 591 parser.close(); 592 return true; 593 } 594 } 595 596 static class ReadXmlAttrsOp extends Op { 597 Context mContext; 598 XmlResourceParser mParser; 599 AttributeSet mAttrs; 600 601 ReadXmlAttrsOp() { 602 super("ReadXmlAttrs", "Read attributes from an XML tag"); 603 } 604 605 void onInit(Context context, boolean foreground) { 606 mContext = context; 607 mParser = mContext.getResources().getLayout(R.xml.simple); 608 mAttrs = Xml.asAttributeSet(mParser); 609 610 int eventType; 611 try { 612 // Find the first <item> tag. 613 eventType = mParser.getEventType(); 614 String tagName; 615 do { 616 if (eventType == XmlPullParser.START_TAG) { 617 tagName = mParser.getName(); 618 if (tagName.equals("item")) { 619 break; 620 } 621 } 622 eventType = mParser.next(); 623 } while (eventType != XmlPullParser.END_DOCUMENT); 624 } catch (XmlPullParserException e) { 625 throw new RuntimeException("I died", e); 626 } catch (IOException e) { 627 throw new RuntimeException("I died", e); 628 } 629 } 630 631 void onTerm(Context context) { 632 mParser.close(); 633 } 634 635 boolean onRun() { 636 TypedArray a = mContext.obtainStyledAttributes(mAttrs, 637 com.android.internal.R.styleable.MenuItem); 638 a.recycle(); 639 return true; 640 } 641 } 642 643 static class ParseXmlResOp extends Op { 644 Context mContext; 645 646 ParseXmlResOp() { 647 super("ParseXmlRes", "Parse compiled XML resource"); 648 } 649 650 void onInit(Context context, boolean foreground) { 651 mContext = context; 652 } 653 654 boolean onRun() { 655 SimpleInflater inf = new SimpleInflater(mContext); 656 inf.inflate(R.xml.simple); 657 return true; 658 } 659 } 660 661 static class ParseLargeXmlResOp extends Op { 662 Context mContext; 663 664 ParseLargeXmlResOp() { 665 super("ParseLargeXmlRes", "Parse large XML resource"); 666 } 667 668 void onInit(Context context, boolean foreground) { 669 mContext = context; 670 } 671 672 boolean onRun() { 673 SimpleInflater inf = new SimpleInflater(mContext); 674 inf.inflate(R.xml.simple_large); 675 return true; 676 } 677 } 678 679 static class LayoutInflaterOp extends Op { 680 Context mContext; 681 682 LayoutInflaterOp() { 683 super("LayoutInflater", "Inflate layout resource"); 684 } 685 686 void onInit(Context context, boolean foreground) { 687 mContext = context; 688 } 689 690 boolean onRun() { 691 if (Looper.myLooper() == null) { 692 Looper.prepare(); 693 } 694 LayoutInflater inf = (LayoutInflater)mContext.getSystemService( 695 Context.LAYOUT_INFLATER_SERVICE); 696 inf.inflate(R.layout.small_layout, null); 697 return true; 698 } 699 } 700 701 static class LayoutInflaterLargeOp extends Op { 702 Context mContext; 703 704 LayoutInflaterLargeOp() { 705 super("LayoutInflaterLarge", "Inflate large layout resource"); 706 } 707 708 void onInit(Context context, boolean foreground) { 709 mContext = context; 710 } 711 712 boolean onRun() { 713 if (Looper.myLooper() == null) { 714 Looper.prepare(); 715 } 716 LayoutInflater inf = (LayoutInflater)mContext.getSystemService( 717 Context.LAYOUT_INFLATER_SERVICE); 718 inf.inflate(R.layout.large_layout, null); 719 return true; 720 } 721 } 722 723 static class LayoutInflaterViewOp extends Op { 724 Context mContext; 725 726 LayoutInflaterViewOp() { 727 super("LayoutInflaterView", "Inflate layout with 50 View objects"); 728 } 729 730 void onInit(Context context, boolean foreground) { 731 mContext = context; 732 } 733 734 boolean onRun() { 735 if (Looper.myLooper() == null) { 736 Looper.prepare(); 737 } 738 LayoutInflater inf = (LayoutInflater)mContext.getSystemService( 739 Context.LAYOUT_INFLATER_SERVICE); 740 inf.inflate(R.layout.view_layout, null); 741 return true; 742 } 743 } 744 745 static class LayoutInflaterButtonOp extends Op { 746 Context mContext; 747 748 LayoutInflaterButtonOp() { 749 super("LayoutInflaterButton", "Inflate layout with 50 Button objects"); 750 } 751 752 void onInit(Context context, boolean foreground) { 753 mContext = context; 754 } 755 756 boolean onRun() { 757 if (Looper.myLooper() == null) { 758 Looper.prepare(); 759 } 760 LayoutInflater inf = (LayoutInflater)mContext.getSystemService( 761 Context.LAYOUT_INFLATER_SERVICE); 762 inf.inflate(R.layout.button_layout, null); 763 return true; 764 } 765 } 766 767 static class LayoutInflaterImageButtonOp extends Op { 768 Context mContext; 769 770 LayoutInflaterImageButtonOp() { 771 super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects"); 772 } 773 774 void onInit(Context context, boolean foreground) { 775 mContext = context; 776 } 777 778 boolean onRun() { 779 if (Looper.myLooper() == null) { 780 Looper.prepare(); 781 } 782 LayoutInflater inf = (LayoutInflater)mContext.getSystemService( 783 Context.LAYOUT_INFLATER_SERVICE); 784 inf.inflate(R.layout.image_button_layout, null); 785 return true; 786 } 787 } 788 789 static class CreateBitmapOp extends Op { 790 Context mContext; 791 792 CreateBitmapOp() { 793 super("CreateBitmap", "Create a Bitmap"); 794 } 795 796 void onInit(Context context, boolean foreground) { 797 mContext = context; 798 } 799 800 boolean onRun() { 801 BitmapFactory.Options opts = new BitmapFactory.Options(); 802 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 803 Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); 804 return true; 805 } 806 } 807 808 static class CreateRecycleBitmapOp extends Op { 809 Context mContext; 810 811 CreateRecycleBitmapOp() { 812 super("CreateRecycleBitmap", "Create and recycle a Bitmap"); 813 } 814 815 void onInit(Context context, boolean foreground) { 816 mContext = context; 817 } 818 819 boolean onRun() { 820 BitmapFactory.Options opts = new BitmapFactory.Options(); 821 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 822 Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); 823 bm.recycle(); 824 return true; 825 } 826 } 827 828 static class LoadSmallBitmapOp extends Op { 829 Context mContext; 830 831 LoadSmallBitmapOp() { 832 super("LoadSmallBitmap", "Load small raw bitmap"); 833 } 834 835 void onInit(Context context, boolean foreground) { 836 mContext = context; 837 } 838 839 boolean onRun() { 840 BitmapFactory.Options opts = new BitmapFactory.Options(); 841 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 842 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 843 R.drawable.stat_sample, opts); 844 return true; 845 } 846 } 847 848 static class LoadRecycleSmallBitmapOp extends Op { 849 Context mContext; 850 851 LoadRecycleSmallBitmapOp() { 852 super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap"); 853 } 854 855 void onInit(Context context, boolean foreground) { 856 mContext = context; 857 } 858 859 boolean onRun() { 860 BitmapFactory.Options opts = new BitmapFactory.Options(); 861 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 862 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 863 R.drawable.stat_sample, opts); 864 bm.recycle(); 865 return true; 866 } 867 } 868 869 static class LoadLargeBitmapOp extends Op { 870 Context mContext; 871 872 LoadLargeBitmapOp() { 873 super("LoadLargeBitmap", "Load large raw bitmap"); 874 } 875 876 void onInit(Context context, boolean foreground) { 877 mContext = context; 878 } 879 880 boolean onRun() { 881 BitmapFactory.Options opts = new BitmapFactory.Options(); 882 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 883 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 884 R.drawable.wallpaper_goldengate, opts); 885 return true; 886 } 887 } 888 889 static class LoadRecycleLargeBitmapOp extends Op { 890 Context mContext; 891 892 LoadRecycleLargeBitmapOp() { 893 super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap"); 894 } 895 896 void onInit(Context context, boolean foreground) { 897 mContext = context; 898 } 899 900 boolean onRun() { 901 BitmapFactory.Options opts = new BitmapFactory.Options(); 902 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 903 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 904 R.drawable.wallpaper_goldengate, opts); 905 bm.recycle(); 906 return true; 907 } 908 } 909 910 static class LoadSmallScaledBitmapOp extends Op { 911 Context mContext; 912 913 LoadSmallScaledBitmapOp() { 914 super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density"); 915 } 916 917 void onInit(Context context, boolean foreground) { 918 mContext = context; 919 } 920 921 boolean onRun() { 922 BitmapFactory.Options opts = new BitmapFactory.Options(); 923 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 924 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 925 R.drawable.stat_sample_scale, opts); 926 return true; 927 } 928 } 929 930 static class LoadLargeScaledBitmapOp extends Op { 931 Context mContext; 932 933 LoadLargeScaledBitmapOp() { 934 super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density"); 935 } 936 937 void onInit(Context context, boolean foreground) { 938 mContext = context; 939 } 940 941 boolean onRun() { 942 BitmapFactory.Options opts = new BitmapFactory.Options(); 943 opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; 944 Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), 945 R.drawable.wallpaper_goldengate_scale, opts); 946 return true; 947 } 948 } 949 950 static class CreateFileOp extends Op { 951 File mFile; 952 953 CreateFileOp() { 954 super("CreateFile", "Create and delete a file"); 955 } 956 957 void onInit(Context context, boolean foreground) { 958 mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); 959 mFile.delete(); 960 } 961 962 boolean onRun() { 963 try { 964 mFile.createNewFile(); 965 } catch (IOException e) { 966 Log.w(TAG, "Failure creating " + mFile, e); 967 } 968 mFile.delete(); 969 return true; 970 } 971 } 972 973 static class CreateWriteFileOp extends Op { 974 File mFile; 975 976 CreateWriteFileOp() { 977 super("CreateWriteFile", "Create, write, and delete a file"); 978 } 979 980 void onInit(Context context, boolean foreground) { 981 mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); 982 mFile.delete(); 983 } 984 985 boolean onRun() { 986 try { 987 FileOutputStream fos = new FileOutputStream(mFile); 988 fos.write(1); 989 fos.close(); 990 } catch (IOException e) { 991 Log.w(TAG, "Failure creating " + mFile, e); 992 } 993 mFile.delete(); 994 return true; 995 } 996 } 997 998 static class CreateWriteSyncFileOp extends Op { 999 File mFile; 1000 1001 CreateWriteSyncFileOp() { 1002 super("CreateWriteSyncFile", "Create, write, sync, and delete a file"); 1003 } 1004 1005 void onInit(Context context, boolean foreground) { 1006 mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); 1007 mFile.delete(); 1008 } 1009 1010 boolean onRun() { 1011 try { 1012 FileOutputStream fos = new FileOutputStream(mFile); 1013 fos.write(1); 1014 fos.flush(); 1015 FileUtils.sync(fos); 1016 fos.close(); 1017 } catch (IOException e) { 1018 Log.w(TAG, "Failure creating " + mFile, e); 1019 } 1020 mFile.delete(); 1021 return true; 1022 } 1023 } 1024 1025 static class WriteFileOp extends Op { 1026 File mFile; 1027 RandomAccessFile mRAF; 1028 byte[] mBuffer; 1029 1030 WriteFileOp() { 1031 super("WriteFile", "Truncate and write a 64k file"); 1032 } 1033 1034 void onInit(Context context, boolean foreground) { 1035 mBuffer = new byte[1024*64]; 1036 for (int i=0; i<mBuffer.length; i++) { 1037 mBuffer[i] = (byte)i; 1038 } 1039 mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); 1040 mFile.delete(); 1041 try { 1042 mRAF = new RandomAccessFile(mFile, "rw"); 1043 } catch (FileNotFoundException e) { 1044 Log.w(TAG, "Failure creating " + mFile, e); 1045 } 1046 } 1047 1048 boolean onRun() { 1049 try { 1050 mRAF.seek(0); 1051 mRAF.setLength(0); 1052 mRAF.write(mBuffer); 1053 } catch (IOException e) { 1054 Log.w(TAG, "Failure writing " + mFile, e); 1055 } 1056 return true; 1057 } 1058 1059 void onTerm(Context context) { 1060 try { 1061 mRAF.close(); 1062 } catch (IOException e) { 1063 Log.w(TAG, "Failure closing " + mFile, e); 1064 } 1065 mFile.delete(); 1066 } 1067 } 1068 1069 static class ReadFileOp extends Op { 1070 File mFile; 1071 RandomAccessFile mRAF; 1072 byte[] mBuffer; 1073 1074 ReadFileOp() { 1075 super("ReadFile", "Seek and read a 64k file"); 1076 } 1077 1078 void onInit(Context context, boolean foreground) { 1079 mBuffer = new byte[1024*64]; 1080 for (int i=0; i<mBuffer.length; i++) { 1081 mBuffer[i] = (byte)i; 1082 } 1083 mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); 1084 mFile.delete(); 1085 try { 1086 mRAF = new RandomAccessFile(mFile, "rw"); 1087 mRAF.seek(0); 1088 mRAF.setLength(0); 1089 mRAF.write(mBuffer); 1090 } catch (IOException e) { 1091 Log.w(TAG, "Failure creating " + mFile, e); 1092 } 1093 } 1094 1095 boolean onRun() { 1096 try { 1097 mRAF.seek(0); 1098 mRAF.read(mBuffer); 1099 } catch (IOException e) { 1100 Log.w(TAG, "Failure reading " + mFile, e); 1101 } 1102 return true; 1103 } 1104 1105 void onTerm(Context context) { 1106 try { 1107 mRAF.close(); 1108 } catch (IOException e) { 1109 Log.w(TAG, "Failure closing " + mFile, e); 1110 } 1111 mFile.delete(); 1112 } 1113 } 1114 } 1115