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