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