From 6b57b7e4d568bfa6273f87ef4c9af2fdc0ca1a06 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 7 Nov 2011 14:45:49 -0800 Subject: [PATCH] Update perf tests to always run each test in a fresh process. Also some new classes to preload. Change-Id: Ia2b5f856eaee533b9603b533ebaf8cb55e2ac193 --- preloaded-classes | 45 + tests/FrameworkPerf/AndroidManifest.xml | 4 + tests/FrameworkPerf/res/layout/main.xml | 5 + .../frameworkperf/FrameworkPerfActivity.java | 1191 +++-------------- .../frameworkperf/LocalTestService.java | 6 + .../com/android/frameworkperf/RunResult.java | 85 ++ .../com/android/frameworkperf/TestArgs.java | 61 + .../android/frameworkperf/TestService.java | 1037 ++++++++++++++ 8 files changed, 1399 insertions(+), 1035 deletions(-) create mode 100644 tests/FrameworkPerf/src/com/android/frameworkperf/LocalTestService.java create mode 100644 tests/FrameworkPerf/src/com/android/frameworkperf/RunResult.java create mode 100644 tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java create mode 100644 tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java diff --git a/preloaded-classes b/preloaded-classes index 31d49ce2851a2..c29ba1560dbae 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -18,7 +18,12 @@ android.accounts.IAccountManagerResponse android.accounts.IAccountManagerResponse$Stub android.animation.Animator android.animation.Animator$AnimatorListener +android.animation.AnimatorInflater android.animation.AnimatorListenerAdapter +android.animation.AnimatorSet +android.animation.AnimatorSet$AnimatorSetListener +android.animation.AnimatorSet$Builder +android.animation.AnimatorSet$Node android.animation.FloatEvaluator android.animation.FloatKeyframeSet android.animation.IntEvaluator @@ -57,6 +62,7 @@ android.app.ActivityThread$CreateServiceData android.app.ActivityThread$GcIdler android.app.ActivityThread$H android.app.ActivityThread$Idler +android.app.ActivityThread$Profiler android.app.ActivityThread$ProviderClientRecord android.app.ActivityThread$ProviderRefCount android.app.ActivityThread$ReceiverData @@ -71,6 +77,8 @@ android.app.ApplicationLoaders android.app.ApplicationPackageManager android.app.ApplicationPackageManager$ResourceName android.app.ApplicationThreadNative +android.app.BackStackRecord +android.app.BackStackRecord$Op android.app.ContextImpl android.app.ContextImpl$1 android.app.ContextImpl$10 @@ -111,9 +119,15 @@ android.app.ContextImpl$StaticServiceFetcher android.app.Dialog android.app.Dialog$1 android.app.Dialog$ListenersHandler +android.app.DialogFragment +android.app.Fragment android.app.FragmentManager +android.app.FragmentManager$BackStackEntry android.app.FragmentManagerImpl android.app.FragmentManagerImpl$1 +android.app.FragmentManagerImpl$2 +android.app.FragmentManagerImpl$3 +android.app.FragmentTransaction android.app.IActivityManager android.app.IActivityManager$ContentProviderHolder android.app.IActivityManager$ContentProviderHolder$1 @@ -134,6 +148,10 @@ android.app.Instrumentation android.app.IntentReceiverLeaked android.app.IntentService android.app.IntentService$ServiceHandler +android.app.ListActivity +android.app.ListActivity$1 +android.app.ListActivity$2 +android.app.ListFragment android.app.LoadedApk android.app.LoadedApk$ReceiverDispatcher android.app.LoadedApk$ReceiverDispatcher$Args @@ -328,6 +346,7 @@ android.emoji.EmojiFactory android.graphics.AvoidXfermode android.graphics.Bitmap android.graphics.Bitmap$1 +android.graphics.Bitmap$2 android.graphics.Bitmap$BitmapFinalizer android.graphics.Bitmap$Config android.graphics.BitmapFactory @@ -719,6 +738,7 @@ android.text.style.LineHeightSpan android.text.style.MetricAffectingSpan android.text.style.ParagraphStyle android.text.style.ReplacementSpan +android.text.style.SpellCheckSpan android.text.style.StyleSpan android.text.style.SuggestionSpan android.text.style.UpdateAppearance @@ -870,6 +890,7 @@ android.view.View$OnLongClickListener android.view.View$OnTouchListener android.view.View$PerformClick android.view.View$ScrollabilityCache +android.view.View$TransformationInfo android.view.View$UnsetPressedState android.view.ViewConfiguration android.view.ViewGroup @@ -934,6 +955,7 @@ android.view.inputmethod.EditorInfo$1 android.view.inputmethod.ExtractedText android.view.inputmethod.ExtractedText$1 android.view.inputmethod.InputConnection +android.view.inputmethod.InputConnectionWrapper android.view.inputmethod.InputMethodManager android.view.inputmethod.InputMethodManager$1 android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper @@ -946,12 +968,16 @@ android.webkit.WebViewCore android.widget.AbsListView android.widget.AbsListView$1 android.widget.AbsListView$2 +android.widget.AbsListView$3 android.widget.AbsListView$AdapterDataSetObserver android.widget.AbsListView$CheckForTap +android.widget.AbsListView$FlingRunnable +android.widget.AbsListView$FlingRunnable$1 android.widget.AbsListView$LayoutParams android.widget.AbsListView$OnScrollListener android.widget.AbsListView$PerformClick android.widget.AbsListView$RecycleBin +android.widget.AbsListView$RecyclerListener android.widget.AbsListView$SavedState android.widget.AbsListView$SavedState$1 android.widget.AbsListView$SelectionBoundsAdjuster @@ -975,13 +1001,19 @@ android.widget.CheckBox android.widget.Checkable android.widget.CheckedTextView android.widget.CompoundButton +android.widget.CompoundButton$OnCheckedChangeListener android.widget.CursorAdapter android.widget.CursorFilter$CursorFilterClient +android.widget.EdgeEffect android.widget.EdgeGlow android.widget.EditText android.widget.ExpandableListView +android.widget.FastScroller +android.widget.FastScroller$1 +android.widget.FastScroller$ScrollFade android.widget.Filter android.widget.Filter$FilterListener +android.widget.Filter$FilterResults android.widget.Filter$ResultsHandler android.widget.Filterable android.widget.FrameLayout @@ -1030,17 +1062,30 @@ android.widget.SearchView android.widget.Spinner android.widget.SpinnerAdapter android.widget.StackView +android.widget.Switch android.widget.TabHost +android.widget.TabHost$ContentStrategy +android.widget.TabHost$FactoryContentStrategy +android.widget.TabHost$IndicatorStrategy +android.widget.TabHost$LabelAndIconIndicatorStrategy +android.widget.TabHost$OnTabChangeListener +android.widget.TabHost$TabContentFactory +android.widget.TabHost$TabSpec +android.widget.TabHost$ViewIndicatorStrategy android.widget.TabWidget +android.widget.TabWidget$OnTabSelectionChanged +android.widget.TabWidget$TabClickListener android.widget.TableLayout android.widget.TableRow android.widget.TextView +android.widget.TextView$2 android.widget.TextView$3 android.widget.TextView$Blink android.widget.TextView$BufferType android.widget.TextView$ChangeWatcher android.widget.TextView$CharWrapper android.widget.TextView$Drawables +android.widget.TextView$EasyEditSpanController android.widget.TextView$InputContentType android.widget.TextView$InputMethodState android.widget.TextView$OnEditorActionListener diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml index aa663f3b78f2f..e88f4fb6e02f1 100644 --- a/tests/FrameworkPerf/AndroidManifest.xml +++ b/tests/FrameworkPerf/AndroidManifest.xml @@ -13,6 +13,10 @@ + + + + diff --git a/tests/FrameworkPerf/res/layout/main.xml b/tests/FrameworkPerf/res/layout/main.xml index 62b1a7ae36a5c..781264881cebd 100644 --- a/tests/FrameworkPerf/res/layout/main.xml +++ b/tests/FrameworkPerf/res/layout/main.xml @@ -91,6 +91,11 @@ android:layout_height="wrap_content" android:text="@string/stop" /> + mResults = new ArrayList(); + class TestConnection implements ServiceConnection { + Messenger mService; + + @Override public void onServiceConnected(ComponentName name, IBinder service) { + mService = new Messenger(service); + dispatchCurOp(this); + } + + @Override public void onServiceDisconnected(ComponentName name) { + } + } + + static final int MSG_CONTINUE = 1000; + + final Handler mHandler = new Handler() { + @Override public void handleMessage(Message msg) { + switch (msg.what) { + case TestService.RES_TEST_FINISHED: { + Bundle bundle = (Bundle)msg.obj; + bundle.setClassLoader(getClassLoader()); + RunResult res = (RunResult)bundle.getParcelable("res"); + completeCurOp(res); + } break; + case TestService.RES_TERMINATED: { + // Give a little time for things to settle down. + sendMessageDelayed(obtainMessage(MSG_CONTINUE), 500); + } break; + case MSG_CONTINUE: { + startCurOp(); + } break; + } + } + }; + + final Messenger mMessenger = new Messenger(mHandler); + public FrameworkPerfActivity() { - mAvailOpLabels = new String[mAvailOps.length]; - mAvailOpDescriptions = new String[mAvailOps.length]; - for (int i=0; i parent, View view, int position, long id) { if (parent == mFgSpinner || parent == mBgSpinner) { - Op op = mAvailOps[position]; + TestService.Op op = TestService.mAvailOps[position]; if (parent == mFgSpinner) { + mFgTestIndex = position; mFgTest = op; ((TextView)findViewById(R.id.fgtext)).setText(mAvailOpDescriptions[position]); } else { + mBgTestIndex = position; mBgTest = op; ((TextView)findViewById(R.id.bgtext)).setText(mAvailOpDescriptions[position]); } @@ -291,64 +203,108 @@ public class FrameworkPerfActivity extends Activity } } - void startCurOp() { - Op fgOp, bgOp; - if (mFgTest == null && mBgTest == null) { - fgOp = mOpPairs[mCurOpIndex]; - bgOp = mOpPairs[mCurOpIndex+1]; - } else if (mFgTest != null && mBgTest != null) { - fgOp = mFgTest; - bgOp = mBgTest; - } else if (mFgTest != null) { - // Skip null test. - if (mCurOpIndex == 0) { - mCurOpIndex = 1; - } - fgOp = mFgTest; - bgOp = mAvailOps[mCurOpIndex]; + void dispatchCurOp(TestConnection conn) { + if (mCurConnection != conn) { + Log.w(TAG, "Dispatching on invalid connection: " + conn); + return; + } + TestArgs args = new TestArgs(); + args.maxTime = mMaxRunTime; + if (mFgTestIndex == 0 && mBgTestIndex == 0) { + args.combOp = mCurOpIndex; + } else if (mFgTestIndex != 0 && mBgTestIndex != 0) { + args.fgOp = mFgTestIndex; + args.bgOp = mBgTestIndex; } else { // Skip null test. if (mCurOpIndex == 0) { mCurOpIndex = 1; } - fgOp = mAvailOps[mCurOpIndex]; - bgOp = mBgTest; - } - mRunner.run(mHandler, fgOp, bgOp, new Runnable() { - @Override public void run() { - RunResult result = new RunResult(mRunner); - log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)", - result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime, - result.bgOps, result.getBgMsPerOp(), result.bgTime)); - mResults.add(result); - if (!mStarted) { - log("Stop"); - stopRunning(); - return; - } - if (mFgTest != null && mBgTest != null) { - log("Finished"); - stopRunning(); - return; - } - if (mFgTest == null && mBgTest == null) { - mCurOpIndex+=2; - if (mCurOpIndex >= mOpPairs.length) { - log("Finished"); - stopRunning(); - return; - } - } else { - mCurOpIndex++; - if (mCurOpIndex >= mAvailOps.length) { - log("Finished"); - stopRunning(); - return; - } - } - startCurOp(); + if (mFgTestIndex != 0) { + args.fgOp = mFgTestIndex; + args.bgOp = mCurOpIndex; + } else { + args.fgOp = mCurOpIndex; + args.bgOp = mFgTestIndex; } - }); + } + Bundle bundle = new Bundle(); + bundle.putParcelable("args", args); + Message msg = Message.obtain(null, TestService.CMD_START_TEST, bundle); + msg.replyTo = mMessenger; + try { + conn.mService.send(msg); + } catch (RemoteException e) { + Log.i(TAG, "Failure communicating with service", e); + } + } + + void completeCurOp(RunResult result) { + log(String.format("%s: fg=%d*%gms/op (%dms) / bg=%d*%gms/op (%dms)", + result.name, result.fgOps, result.getFgMsPerOp(), result.fgTime, + result.bgOps, result.getBgMsPerOp(), result.bgTime)); + mResults.add(result); + if (!mStarted) { + log("Stop"); + stopRunning(); + return; + } + if (mFgTest != null && mBgTest != null) { + log("Finished"); + stopRunning(); + return; + } + if (mFgTest == null && mBgTest == null) { + mCurOpIndex+=2; + if (mCurOpIndex >= TestService.mOpPairs.length) { + log("Finished"); + stopRunning(); + return; + } + } else { + mCurOpIndex++; + if (mCurOpIndex >= TestService.mAvailOps.length) { + log("Finished"); + stopRunning(); + return; + } + } + startCurOp(); + } + + void disconnect() { + if (mCurConnection != null) { + unbindService(mCurConnection); + if (mCurConnection.mService != null) { + Message msg = Message.obtain(null, TestService.CMD_TERMINATE); + msg.replyTo = mMessenger; + try { + mCurConnection.mService.send(msg); + } catch (RemoteException e) { + Log.i(TAG, "Failure communicating with service", e); + } + } + mCurConnection = null; + } + } + + void startCurOp() { + if (mCurConnection != null) { + disconnect(); + } + if (mStarted) { + mHandler.removeMessages(TestService.RES_TEST_FINISHED); + mHandler.removeMessages(TestService.RES_TERMINATED); + mHandler.removeMessages(MSG_CONTINUE); + mCurConnection = new TestConnection(); + Intent intent; + if (mLocalCheckBox.isChecked()) { + intent = new Intent(this, LocalTestService.class); + } else { + intent = new Intent(this, TestService.class); + } + bindService(intent, mCurConnection, BIND_AUTO_CREATE|BIND_IMPORTANT); + } } void startRunning() { @@ -357,6 +313,7 @@ public class FrameworkPerfActivity extends Activity mStarted = true; mStartButton.setEnabled(false); mStopButton.setEnabled(true); + mLocalCheckBox.setEnabled(false); mTestTime.setEnabled(false); mFgSpinner.setEnabled(false); mBgSpinner.setEnabled(false); @@ -371,9 +328,11 @@ public class FrameworkPerfActivity extends Activity void stopRunning() { if (mStarted) { + disconnect(); mStarted = false; mStartButton.setEnabled(true); mStopButton.setEnabled(false); + mLocalCheckBox.setEnabled(true); mTestTime.setEnabled(true); mFgSpinner.setEnabled(true); mBgSpinner.setEnabled(true); @@ -412,842 +371,4 @@ public class FrameworkPerfActivity extends Activity mLog.setText(mLog.getText() + "\n" + s); Log.i(TAG, s); } - - enum BackgroundMode { - NOTHING, - CPU, - SCHEDULER - }; - - public class TestRunner { - Handler mHandler; - Op mForegroundOp; - Op mBackgroundOp; - Runnable mDoneCallback; - - RunnerThread mBackgroundThread; - RunnerThread mForegroundThread; - long mStartTime; - - boolean mBackgroundRunning; - boolean mForegroundRunning; - - long mBackgroundEndTime; - long mBackgroundOps; - long mForegroundEndTime; - long mForegroundOps; - - public TestRunner() { - } - - public String getForegroundName() { - return mForegroundOp.getName(); - } - - public String getBackgroundName() { - return mBackgroundOp.getName(); - } - - public String getName() { - String fgName = mForegroundOp.getName(); - String bgName = mBackgroundOp.getName(); - StringBuilder res = new StringBuilder(); - if (fgName != null) { - res.append(fgName); - res.append("Fg"); - } - if (bgName != null) { - res.append(bgName); - res.append("Bg"); - } - return res.toString(); - } - - public String getForegroundLongName() { - return mForegroundOp.getLongName(); - } - - public String getBackgroundLongName() { - return mBackgroundOp.getLongName(); - } - - public void run(Handler handler, Op foreground, Op background, Runnable doneCallback) { - mHandler = handler; - mForegroundOp = foreground; - mBackgroundOp = background; - mDoneCallback = doneCallback; - mBackgroundThread = new RunnerThread("background", new Runnable() { - @Override public void run() { - boolean running; - int ops = 0; - do { - running = mBackgroundOp.onRun(); - ops++; - } while (evalRepeat(running, true) && running); - mBackgroundEndTime = SystemClock.uptimeMillis(); - mBackgroundOps = ops * mBackgroundOp.getOpsPerRun(); - threadFinished(false); - } - }, Process.THREAD_PRIORITY_BACKGROUND); - mForegroundThread = new RunnerThread("background", new Runnable() { - @Override public void run() { - boolean running; - int ops = 0; - do { - running = mForegroundOp.onRun(); - ops++; - } while (evalRepeat(true, running) && running); - mForegroundEndTime = SystemClock.uptimeMillis(); - mForegroundOps = ops * mForegroundOp.getOpsPerRun(); - threadFinished(true); - } - }, Process.THREAD_PRIORITY_FOREGROUND); - - mForegroundOp.onInit(FrameworkPerfActivity.this, true); - mBackgroundOp.onInit(FrameworkPerfActivity.this, false); - - synchronized (this) { - mStartTime = SystemClock.uptimeMillis(); - mBackgroundRunning = true; - mForegroundRunning = true; - } - - mBackgroundThread.start(); - mForegroundThread.start(); - } - - public long getForegroundTime() { - return mForegroundEndTime-mStartTime; - } - - public long getForegroundOps() { - return mForegroundOps; - } - - public long getBackgroundTime() { - return mBackgroundEndTime-mStartTime; - } - - public long getBackgroundOps() { - return mBackgroundOps; - } - - private boolean evalRepeat(boolean bgRunning, boolean fgRunning) { - synchronized (this) { - if (!bgRunning) { - mBackgroundRunning = false; - } - if (!fgRunning) { - mForegroundRunning = false; - } - if (!mBackgroundRunning && !mForegroundRunning) { - return false; - } - long now = SystemClock.uptimeMillis(); - if (now > (mStartTime+mMaxRunTime)) { - return false; - } - return true; - } - } - - private void threadFinished(boolean foreground) { - synchronized (this) { - if (foreground) { - mForegroundRunning = false; - } else { - mBackgroundRunning = false; - } - if (!mBackgroundRunning && !mForegroundRunning) { - mHandler.post(new Runnable() { - @Override public void run() { - mForegroundOp.onTerm(FrameworkPerfActivity.this); - mBackgroundOp.onTerm(FrameworkPerfActivity.this); - if (mDoneCallback != null) { - mDoneCallback.run(); - } - } - }); - } - } - } - } - - class RunnerThread extends Thread { - private final Runnable mOp; - private final int mPriority; - - RunnerThread(String name, Runnable op, int priority) { - super(name); - mOp = op; - mPriority = priority; - } - - public void run() { - Process.setThreadPriority(mPriority); - mOp.run(); - } - } - - static public abstract class Op { - final String mName; - final String mLongName; - - public Op(String name, String longName) { - mName = name; - mLongName = longName; - } - - public String getName() { - return mName; - } - - public String getLongName() { - return mLongName; - } - - void onInit(Context context, boolean foreground) { - } - - abstract boolean onRun(); - - void onTerm(Context context) { - } - - int getOpsPerRun() { - return 1; - } - } - - static class NoOp extends Op { - NoOp() { - super(null, "Nothing"); - } - - boolean onRun() { - return false; - } - - int getOpsPerRun() { - return 0; - } - } - - static class CpuOp extends Op { - CpuOp() { - super("CPU", "Consume CPU"); - } - - boolean onRun() { - return true; - } - } - - static class SchedulerOp extends Op { - SchedulerOp() { - super("Sched", "Change scheduler group"); - } - - boolean onRun() { - Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); - Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); - return true; - } - } - - static class GcOp extends Op { - GcOp() { - super("Gc", "Run garbage collector"); - } - - boolean onRun() { - byte[] stuff = new byte[1024*1024]; - return true; - } - } - - static class MethodCallOp extends Op { - MethodCallOp() { - super("MethodCall", "Method call"); - } - - boolean onRun() { - final int N = getOpsPerRun(); - for (int i=0; i tag. - eventType = mParser.getEventType(); - String tagName; - do { - if (eventType == XmlPullParser.START_TAG) { - tagName = mParser.getName(); - if (tagName.equals("item")) { - break; - } - } - eventType = mParser.next(); - } while (eventType != XmlPullParser.END_DOCUMENT); - } catch (XmlPullParserException e) { - throw new RuntimeException("I died", e); - } catch (IOException e) { - throw new RuntimeException("I died", e); - } - } - - void onTerm(Context context) { - mParser.close(); - } - - boolean onRun() { - TypedArray a = mContext.obtainStyledAttributes(mAttrs, - com.android.internal.R.styleable.MenuItem); - a.recycle(); - return true; - } - } - - static class ParseXmlResOp extends Op { - Context mContext; - - ParseXmlResOp() { - super("ParseXmlRes", "Parse compiled XML resource"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - SimpleInflater inf = new SimpleInflater(mContext); - inf.inflate(R.xml.simple); - return true; - } - } - - static class ParseLargeXmlResOp extends Op { - Context mContext; - - ParseLargeXmlResOp() { - super("ParseLargeXmlRes", "Parse large XML resource"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - SimpleInflater inf = new SimpleInflater(mContext); - inf.inflate(R.xml.simple_large); - return true; - } - } - - static class LayoutInflaterOp extends Op { - Context mContext; - - LayoutInflaterOp() { - super("LayoutInflater", "Inflate layout resource"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - LayoutInflater inf = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - inf.inflate(R.layout.small_layout, null); - return true; - } - } - - static class LayoutInflaterLargeOp extends Op { - Context mContext; - - LayoutInflaterLargeOp() { - super("LayoutInflaterLarge", "Inflate large layout resource"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - LayoutInflater inf = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - inf.inflate(R.layout.large_layout, null); - return true; - } - } - - static class LayoutInflaterViewOp extends Op { - Context mContext; - - LayoutInflaterViewOp() { - super("LayoutInflaterView", "Inflate layout with 50 View objects"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - LayoutInflater inf = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - inf.inflate(R.layout.view_layout, null); - return true; - } - } - - static class LayoutInflaterButtonOp extends Op { - Context mContext; - - LayoutInflaterButtonOp() { - super("LayoutInflaterButton", "Inflate layout with 50 Button objects"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - LayoutInflater inf = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - inf.inflate(R.layout.button_layout, null); - return true; - } - } - - static class LayoutInflaterImageButtonOp extends Op { - Context mContext; - - LayoutInflaterImageButtonOp() { - super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - if (Looper.myLooper() == null) { - Looper.prepare(); - } - LayoutInflater inf = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - inf.inflate(R.layout.image_button_layout, null); - return true; - } - } - - static class CreateBitmapOp extends Op { - Context mContext; - - CreateBitmapOp() { - super("CreateBitmap", "Create a Bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); - return true; - } - } - - static class CreateRecycleBitmapOp extends Op { - Context mContext; - - CreateRecycleBitmapOp() { - super("CreateRecycleBitmap", "Create and recycle a Bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); - bm.recycle(); - return true; - } - } - - static class LoadSmallBitmapOp extends Op { - Context mContext; - - LoadSmallBitmapOp() { - super("LoadSmallBitmap", "Load small raw bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.stat_sample, opts); - return true; - } - } - - static class LoadRecycleSmallBitmapOp extends Op { - Context mContext; - - LoadRecycleSmallBitmapOp() { - super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.stat_sample, opts); - bm.recycle(); - return true; - } - } - - static class LoadLargeBitmapOp extends Op { - Context mContext; - - LoadLargeBitmapOp() { - super("LoadLargeBitmap", "Load large raw bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.wallpaper_goldengate, opts); - return true; - } - } - - static class LoadRecycleLargeBitmapOp extends Op { - Context mContext; - - LoadRecycleLargeBitmapOp() { - super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.wallpaper_goldengate, opts); - bm.recycle(); - return true; - } - } - - static class LoadSmallScaledBitmapOp extends Op { - Context mContext; - - LoadSmallScaledBitmapOp() { - super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.stat_sample_scale, opts); - return true; - } - } - - static class LoadLargeScaledBitmapOp extends Op { - Context mContext; - - LoadLargeScaledBitmapOp() { - super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density"); - } - - void onInit(Context context, boolean foreground) { - mContext = context; - } - - boolean onRun() { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; - Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.wallpaper_goldengate_scale, opts); - return true; - } - } - - static class CreateFileOp extends Op { - File mFile; - - CreateFileOp() { - super("CreateFile", "Create and delete a file"); - } - - void onInit(Context context, boolean foreground) { - mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); - mFile.delete(); - } - - boolean onRun() { - try { - mFile.createNewFile(); - } catch (IOException e) { - Log.w(TAG, "Failure creating " + mFile, e); - } - mFile.delete(); - return true; - } - } - - static class CreateWriteFileOp extends Op { - File mFile; - - CreateWriteFileOp() { - super("CreateWriteFile", "Create, write, and delete a file"); - } - - void onInit(Context context, boolean foreground) { - mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); - mFile.delete(); - } - - boolean onRun() { - try { - FileOutputStream fos = new FileOutputStream(mFile); - fos.write(1); - fos.close(); - } catch (IOException e) { - Log.w(TAG, "Failure creating " + mFile, e); - } - mFile.delete(); - return true; - } - } - - static class CreateWriteSyncFileOp extends Op { - File mFile; - - CreateWriteSyncFileOp() { - super("CreateWriteSyncFile", "Create, write, sync, and delete a file"); - } - - void onInit(Context context, boolean foreground) { - mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); - mFile.delete(); - } - - boolean onRun() { - try { - FileOutputStream fos = new FileOutputStream(mFile); - fos.write(1); - fos.flush(); - FileUtils.sync(fos); - fos.close(); - } catch (IOException e) { - Log.w(TAG, "Failure creating " + mFile, e); - } - mFile.delete(); - return true; - } - } - - static class WriteFileOp extends Op { - File mFile; - RandomAccessFile mRAF; - byte[] mBuffer; - - WriteFileOp() { - super("WriteFile", "Truncate and write a 64k file"); - } - - void onInit(Context context, boolean foreground) { - mBuffer = new byte[1024*64]; - for (int i=0; i CREATOR + = new Parcelable.Creator() { + public RunResult createFromParcel(Parcel in) { + return new RunResult(in); + } + + public RunResult[] newArray(int size) { + return new RunResult[size]; + } + }; +} \ No newline at end of file diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java new file mode 100644 index 0000000000000..f2f7c5675bcff --- /dev/null +++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.frameworkperf; + +import android.os.Parcel; +import android.os.Parcelable; + +public class TestArgs implements Parcelable { + long maxTime; + int combOp = -1; + int fgOp = -1; + int bgOp = -1; + + public TestArgs() { + } + + public TestArgs(Parcel source) { + maxTime = source.readLong(); + combOp = source.readInt(); + fgOp = source.readInt(); + bgOp = source.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(maxTime); + dest.writeInt(combOp); + dest.writeInt(fgOp); + dest.writeInt(bgOp); + } + + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public TestArgs createFromParcel(Parcel in) { + return new TestArgs(in); + } + + public TestArgs[] newArray(int size) { + return new TestArgs[size]; + } + }; +} diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java new file mode 100644 index 0000000000000..ce27b65e8fd1d --- /dev/null +++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java @@ -0,0 +1,1037 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.frameworkperf; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Bundle; +import android.os.FileUtils; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Messenger; +import android.os.Process; +import android.os.RemoteException; +import android.os.SystemClock; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.Xml; +import android.view.LayoutInflater; + +public class TestService extends Service { + static final String TAG = "Perf"; + + final static Op[] mOpPairs = new Op[] { + new MethodCallOp(), new NoOp(), + new MethodCallOp(), new CpuOp(), + new MethodCallOp(), new SchedulerOp(), + new MethodCallOp(), new GcOp(), + new MethodCallOp(), new CreateFileOp(), + new MethodCallOp(), new CreateWriteFileOp(), + new MethodCallOp(), new CreateWriteSyncFileOp(), + new MethodCallOp(), new WriteFileOp(), + new MethodCallOp(), new ReadFileOp(), + new SchedulerOp(), new SchedulerOp(), + new GcOp(), new NoOp(), + new IpcOp(), new NoOp(), + new IpcOp(), new CpuOp(), + new IpcOp(), new SchedulerOp(), + new IpcOp(), new GcOp(), + new IpcOp(), new CreateFileOp(), + new IpcOp(), new CreateWriteFileOp(), + new IpcOp(), new CreateWriteSyncFileOp(), + new IpcOp(), new WriteFileOp(), + new IpcOp(), new ReadFileOp(), + new CreateFileOp(), new NoOp(), + new CreateWriteFileOp(), new NoOp(), + new CreateWriteSyncFileOp(), new NoOp(), + new WriteFileOp(), new NoOp(), + new ReadFileOp(), new NoOp(), + new WriteFileOp(), new CreateWriteFileOp(), + new ReadFileOp(), new CreateWriteFileOp(), + new WriteFileOp(), new CreateWriteSyncFileOp(), + new ReadFileOp(), new CreateWriteSyncFileOp(), + new WriteFileOp(), new WriteFileOp(), + new WriteFileOp(), new ReadFileOp(), + new ReadFileOp(), new WriteFileOp(), + new ReadFileOp(), new ReadFileOp(), + new OpenXmlResOp(), new NoOp(), + new ReadXmlAttrsOp(), new NoOp(), + new ParseXmlResOp(), new NoOp(), + new ParseLargeXmlResOp(), new NoOp(), + new LayoutInflaterOp(), new NoOp(), + new LayoutInflaterLargeOp(), new NoOp(), + new LayoutInflaterViewOp(), new NoOp(), + new LayoutInflaterButtonOp(), new NoOp(), + new LayoutInflaterImageButtonOp(), new NoOp(), + new CreateBitmapOp(), new NoOp(), + new CreateRecycleBitmapOp(), new NoOp(), + new LoadSmallBitmapOp(), new NoOp(), + new LoadRecycleSmallBitmapOp(), new NoOp(), + new LoadLargeBitmapOp(), new NoOp(), + new LoadRecycleLargeBitmapOp(), new NoOp(), + new LoadSmallScaledBitmapOp(), new NoOp(), + new LoadLargeScaledBitmapOp(), new NoOp(), + }; + + final static Op[] mAvailOps = new Op[] { + null, + new NoOp(), + new CpuOp(), + new SchedulerOp(), + new MethodCallOp(), + new IpcOp(), + new CreateFileOp(), + new CreateWriteFileOp(), + new CreateWriteSyncFileOp(), + new WriteFileOp(), + new ReadFileOp(), + new OpenXmlResOp(), + new ReadXmlAttrsOp(), + new ParseXmlResOp(), + new ParseLargeXmlResOp(), + new LayoutInflaterOp(), + new LayoutInflaterLargeOp(), + new LayoutInflaterViewOp(), + new LayoutInflaterButtonOp(), + new LayoutInflaterImageButtonOp(), + new CreateBitmapOp(), + new CreateRecycleBitmapOp(), + new LoadSmallBitmapOp(), + new LoadRecycleSmallBitmapOp(), + new LoadLargeBitmapOp(), + new LoadRecycleLargeBitmapOp(), + new LoadSmallScaledBitmapOp(), + new LoadLargeScaledBitmapOp(), + }; + + static final int CMD_START_TEST = 1; + static final int CMD_TERMINATE = 2; + + static final int RES_TEST_FINISHED = 1; + static final int RES_TERMINATED = 2; + + final Handler mHandler = new Handler() { + @Override public void handleMessage(Message msg) { + switch (msg.what) { + case CMD_START_TEST: { + Bundle bundle = (Bundle)msg.obj; + bundle.setClassLoader(getClassLoader()); + final TestArgs args = (TestArgs)bundle.getParcelable("args"); + final Messenger replyTo = msg.replyTo; + mRunner.run(this, args, new Runnable() { + @Override public void run() { + if (replyTo != null) { + Message msg = Message.obtain(null, RES_TEST_FINISHED); + Bundle bundle = new Bundle(); + bundle.putParcelable("res", new RunResult(mRunner)); + msg.obj = bundle; + try { + replyTo.send(msg); + } catch (RemoteException e) { + } + } + } + }); + } break; + case CMD_TERMINATE: { + if (msg.replyTo != null) { + Message reply = Message.obtain(null, RES_TERMINATED); + try { + msg.replyTo.send(reply); + } catch (RemoteException e) { + } + } + terminate(); + } + } + } + }; + + final TestRunner mRunner = new TestRunner(); + + @Override + public IBinder onBind(Intent intent) { + return (new Messenger(mHandler)).getBinder(); + } + + void terminate() { + Process.killProcess(Process.myPid()); + } + + enum BackgroundMode { + NOTHING, + CPU, + SCHEDULER + }; + + public class TestRunner { + Handler mHandler; + long mMaxRunTime; + Op mForegroundOp; + Op mBackgroundOp; + Runnable mDoneCallback; + + RunnerThread mBackgroundThread; + RunnerThread mForegroundThread; + long mStartTime; + + boolean mBackgroundRunning; + boolean mForegroundRunning; + + long mBackgroundEndTime; + long mBackgroundOps; + long mForegroundEndTime; + long mForegroundOps; + + public TestRunner() { + } + + public String getForegroundName() { + return mForegroundOp.getName(); + } + + public String getBackgroundName() { + return mBackgroundOp.getName(); + } + + public String getName() { + String fgName = mForegroundOp.getName(); + String bgName = mBackgroundOp.getName(); + StringBuilder res = new StringBuilder(); + if (fgName != null) { + res.append(fgName); + res.append("Fg"); + } + if (bgName != null) { + res.append(bgName); + res.append("Bg"); + } + return res.toString(); + } + + public String getForegroundLongName() { + return mForegroundOp.getLongName(); + } + + public String getBackgroundLongName() { + return mBackgroundOp.getLongName(); + } + + public void run(Handler handler, TestArgs args, Runnable doneCallback) { + mHandler = handler; + mMaxRunTime = args.maxTime; + if (args.combOp >= 0) { + mForegroundOp = mOpPairs[args.combOp]; + mBackgroundOp = mOpPairs[args.combOp+1]; + } else { + mForegroundOp = mAvailOps[args.fgOp]; + mBackgroundOp = mAvailOps[args.bgOp]; + } + mDoneCallback = doneCallback; + mBackgroundThread = new RunnerThread("background", new Runnable() { + @Override public void run() { + boolean running; + int ops = 0; + do { + running = mBackgroundOp.onRun(); + ops++; + } while (evalRepeat(running, true) && running); + mBackgroundEndTime = SystemClock.uptimeMillis(); + mBackgroundOps = ops * mBackgroundOp.getOpsPerRun(); + threadFinished(false); + } + }, Process.THREAD_PRIORITY_BACKGROUND); + mForegroundThread = new RunnerThread("background", new Runnable() { + @Override public void run() { + boolean running; + int ops = 0; + do { + running = mForegroundOp.onRun(); + ops++; + } while (evalRepeat(true, running) && running); + mForegroundEndTime = SystemClock.uptimeMillis(); + mForegroundOps = ops * mForegroundOp.getOpsPerRun(); + threadFinished(true); + } + }, Process.THREAD_PRIORITY_FOREGROUND); + + mForegroundOp.onInit(TestService.this, true); + mBackgroundOp.onInit(TestService.this, false); + + synchronized (this) { + mStartTime = SystemClock.uptimeMillis(); + mBackgroundRunning = true; + mForegroundRunning = true; + } + + mBackgroundThread.start(); + mForegroundThread.start(); + } + + public long getForegroundTime() { + return mForegroundEndTime-mStartTime; + } + + public long getForegroundOps() { + return mForegroundOps; + } + + public long getBackgroundTime() { + return mBackgroundEndTime-mStartTime; + } + + public long getBackgroundOps() { + return mBackgroundOps; + } + + private boolean evalRepeat(boolean bgRunning, boolean fgRunning) { + synchronized (this) { + if (!bgRunning) { + mBackgroundRunning = false; + } + if (!fgRunning) { + mForegroundRunning = false; + } + if (!mBackgroundRunning && !mForegroundRunning) { + return false; + } + long now = SystemClock.uptimeMillis(); + if (now > (mStartTime+mMaxRunTime)) { + return false; + } + return true; + } + } + + private void threadFinished(boolean foreground) { + synchronized (this) { + if (foreground) { + mForegroundRunning = false; + } else { + mBackgroundRunning = false; + } + if (!mBackgroundRunning && !mForegroundRunning) { + mHandler.post(new Runnable() { + @Override public void run() { + mForegroundOp.onTerm(TestService.this); + mBackgroundOp.onTerm(TestService.this); + if (mDoneCallback != null) { + mDoneCallback.run(); + } + } + }); + } + } + } + } + + class RunnerThread extends Thread { + private final Runnable mOp; + private final int mPriority; + + RunnerThread(String name, Runnable op, int priority) { + super(name); + mOp = op; + mPriority = priority; + } + + public void run() { + Process.setThreadPriority(mPriority); + mOp.run(); + } + } + + static public abstract class Op { + final String mName; + final String mLongName; + + public Op(String name, String longName) { + mName = name; + mLongName = longName; + } + + public String getName() { + return mName; + } + + public String getLongName() { + return mLongName; + } + + void onInit(Context context, boolean foreground) { + } + + abstract boolean onRun(); + + void onTerm(Context context) { + } + + int getOpsPerRun() { + return 1; + } + } + + static class NoOp extends Op { + NoOp() { + super(null, "Nothing"); + } + + boolean onRun() { + return false; + } + + int getOpsPerRun() { + return 0; + } + } + + static class CpuOp extends Op { + CpuOp() { + super("CPU", "Consume CPU"); + } + + boolean onRun() { + return true; + } + } + + static class SchedulerOp extends Op { + SchedulerOp() { + super("Sched", "Change scheduler group"); + } + + boolean onRun() { + Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + return true; + } + } + + static class GcOp extends Op { + GcOp() { + super("Gc", "Run garbage collector"); + } + + boolean onRun() { + byte[] stuff = new byte[1024*1024]; + return true; + } + } + + static class MethodCallOp extends Op { + MethodCallOp() { + super("MethodCall", "Method call"); + } + + boolean onRun() { + final int N = getOpsPerRun(); + for (int i=0; i tag. + eventType = mParser.getEventType(); + String tagName; + do { + if (eventType == XmlPullParser.START_TAG) { + tagName = mParser.getName(); + if (tagName.equals("item")) { + break; + } + } + eventType = mParser.next(); + } while (eventType != XmlPullParser.END_DOCUMENT); + } catch (XmlPullParserException e) { + throw new RuntimeException("I died", e); + } catch (IOException e) { + throw new RuntimeException("I died", e); + } + } + + void onTerm(Context context) { + mParser.close(); + } + + boolean onRun() { + TypedArray a = mContext.obtainStyledAttributes(mAttrs, + com.android.internal.R.styleable.MenuItem); + a.recycle(); + return true; + } + } + + static class ParseXmlResOp extends Op { + Context mContext; + + ParseXmlResOp() { + super("ParseXmlRes", "Parse compiled XML resource"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + SimpleInflater inf = new SimpleInflater(mContext); + inf.inflate(R.xml.simple); + return true; + } + } + + static class ParseLargeXmlResOp extends Op { + Context mContext; + + ParseLargeXmlResOp() { + super("ParseLargeXmlRes", "Parse large XML resource"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + SimpleInflater inf = new SimpleInflater(mContext); + inf.inflate(R.xml.simple_large); + return true; + } + } + + static class LayoutInflaterOp extends Op { + Context mContext; + + LayoutInflaterOp() { + super("LayoutInflater", "Inflate layout resource"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + LayoutInflater inf = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inf.inflate(R.layout.small_layout, null); + return true; + } + } + + static class LayoutInflaterLargeOp extends Op { + Context mContext; + + LayoutInflaterLargeOp() { + super("LayoutInflaterLarge", "Inflate large layout resource"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + LayoutInflater inf = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inf.inflate(R.layout.large_layout, null); + return true; + } + } + + static class LayoutInflaterViewOp extends Op { + Context mContext; + + LayoutInflaterViewOp() { + super("LayoutInflaterView", "Inflate layout with 50 View objects"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + LayoutInflater inf = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inf.inflate(R.layout.view_layout, null); + return true; + } + } + + static class LayoutInflaterButtonOp extends Op { + Context mContext; + + LayoutInflaterButtonOp() { + super("LayoutInflaterButton", "Inflate layout with 50 Button objects"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + LayoutInflater inf = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inf.inflate(R.layout.button_layout, null); + return true; + } + } + + static class LayoutInflaterImageButtonOp extends Op { + Context mContext; + + LayoutInflaterImageButtonOp() { + super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + LayoutInflater inf = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inf.inflate(R.layout.image_button_layout, null); + return true; + } + } + + static class CreateBitmapOp extends Op { + Context mContext; + + CreateBitmapOp() { + super("CreateBitmap", "Create a Bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); + return true; + } + } + + static class CreateRecycleBitmapOp extends Op { + Context mContext; + + CreateRecycleBitmapOp() { + super("CreateRecycleBitmap", "Create and recycle a Bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888); + bm.recycle(); + return true; + } + } + + static class LoadSmallBitmapOp extends Op { + Context mContext; + + LoadSmallBitmapOp() { + super("LoadSmallBitmap", "Load small raw bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.stat_sample, opts); + return true; + } + } + + static class LoadRecycleSmallBitmapOp extends Op { + Context mContext; + + LoadRecycleSmallBitmapOp() { + super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.stat_sample, opts); + bm.recycle(); + return true; + } + } + + static class LoadLargeBitmapOp extends Op { + Context mContext; + + LoadLargeBitmapOp() { + super("LoadLargeBitmap", "Load large raw bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.wallpaper_goldengate, opts); + return true; + } + } + + static class LoadRecycleLargeBitmapOp extends Op { + Context mContext; + + LoadRecycleLargeBitmapOp() { + super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.wallpaper_goldengate, opts); + bm.recycle(); + return true; + } + } + + static class LoadSmallScaledBitmapOp extends Op { + Context mContext; + + LoadSmallScaledBitmapOp() { + super("LoadSmallScaledBitmap", "Load small raw bitmap that is scaled for density"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.stat_sample_scale, opts); + return true; + } + } + + static class LoadLargeScaledBitmapOp extends Op { + Context mContext; + + LoadLargeScaledBitmapOp() { + super("LoadLargeScaledBitmap", "Load large raw bitmap that is scaled for density"); + } + + void onInit(Context context, boolean foreground) { + mContext = context; + } + + boolean onRun() { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; + Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(), + R.drawable.wallpaper_goldengate_scale, opts); + return true; + } + } + + static class CreateFileOp extends Op { + File mFile; + + CreateFileOp() { + super("CreateFile", "Create and delete a file"); + } + + void onInit(Context context, boolean foreground) { + mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); + mFile.delete(); + } + + boolean onRun() { + try { + mFile.createNewFile(); + } catch (IOException e) { + Log.w(TAG, "Failure creating " + mFile, e); + } + mFile.delete(); + return true; + } + } + + static class CreateWriteFileOp extends Op { + File mFile; + + CreateWriteFileOp() { + super("CreateWriteFile", "Create, write, and delete a file"); + } + + void onInit(Context context, boolean foreground) { + mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); + mFile.delete(); + } + + boolean onRun() { + try { + FileOutputStream fos = new FileOutputStream(mFile); + fos.write(1); + fos.close(); + } catch (IOException e) { + Log.w(TAG, "Failure creating " + mFile, e); + } + mFile.delete(); + return true; + } + } + + static class CreateWriteSyncFileOp extends Op { + File mFile; + + CreateWriteSyncFileOp() { + super("CreateWriteSyncFile", "Create, write, sync, and delete a file"); + } + + void onInit(Context context, boolean foreground) { + mFile = context.getFileStreamPath(foreground ? "test-fg.file" : "test-bg.file"); + mFile.delete(); + } + + boolean onRun() { + try { + FileOutputStream fos = new FileOutputStream(mFile); + fos.write(1); + fos.flush(); + FileUtils.sync(fos); + fos.close(); + } catch (IOException e) { + Log.w(TAG, "Failure creating " + mFile, e); + } + mFile.delete(); + return true; + } + } + + static class WriteFileOp extends Op { + File mFile; + RandomAccessFile mRAF; + byte[] mBuffer; + + WriteFileOp() { + super("WriteFile", "Truncate and write a 64k file"); + } + + void onInit(Context context, boolean foreground) { + mBuffer = new byte[1024*64]; + for (int i=0; i