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