Home | History | Annotate | Download | only in frameworkperf
      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