diff options
Diffstat (limited to 'tests')
44 files changed, 1826 insertions, 75 deletions
diff --git a/tests/BiDiTests/res/drawable/alphabet_a.png b/tests/BiDiTests/res/drawable/alphabet_a.png Binary files differnew file mode 100644 index 0000000..2a80ec1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_a.png diff --git a/tests/BiDiTests/res/drawable/alphabet_b.png b/tests/BiDiTests/res/drawable/alphabet_b.png Binary files differnew file mode 100644 index 0000000..ac887ad --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_b.png diff --git a/tests/BiDiTests/res/drawable/alphabet_c.png b/tests/BiDiTests/res/drawable/alphabet_c.png Binary files differnew file mode 100644 index 0000000..f8cc5c6 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_c.png diff --git a/tests/BiDiTests/res/drawable/alphabet_d.png b/tests/BiDiTests/res/drawable/alphabet_d.png Binary files differnew file mode 100644 index 0000000..764dfe5 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_d.png diff --git a/tests/BiDiTests/res/drawable/alphabet_e.png b/tests/BiDiTests/res/drawable/alphabet_e.png Binary files differnew file mode 100644 index 0000000..dbd00e1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_e.png diff --git a/tests/BiDiTests/res/drawable/alphabet_f.png b/tests/BiDiTests/res/drawable/alphabet_f.png Binary files differnew file mode 100644 index 0000000..f6a1bbe --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_f.png diff --git a/tests/BiDiTests/res/drawable/alphabet_g.png b/tests/BiDiTests/res/drawable/alphabet_g.png Binary files differnew file mode 100644 index 0000000..e9d360c --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_g.png diff --git a/tests/BiDiTests/res/drawable/alphabet_h.png b/tests/BiDiTests/res/drawable/alphabet_h.png Binary files differnew file mode 100644 index 0000000..cbc4eb1 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_h.png diff --git a/tests/BiDiTests/res/drawable/alphabet_i.png b/tests/BiDiTests/res/drawable/alphabet_i.png Binary files differnew file mode 100644 index 0000000..bae2103 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_i.png diff --git a/tests/BiDiTests/res/drawable/alphabet_j.png b/tests/BiDiTests/res/drawable/alphabet_j.png Binary files differnew file mode 100644 index 0000000..264c6a7 --- /dev/null +++ b/tests/BiDiTests/res/drawable/alphabet_j.png diff --git a/tests/BiDiTests/res/layout/basic.xml b/tests/BiDiTests/res/layout/basic.xml index d438b2c..ed91c49 100644 --- a/tests/BiDiTests/res/layout/basic.xml +++ b/tests/BiDiTests/res/layout/basic.xml @@ -40,7 +40,7 @@ android:textSize="32dip" android:text="@string/textview_text" /> - + <EditText android:id="@+id/edittext" android:layout_height="wrap_content" android:layout_width="match_parent" @@ -49,6 +49,40 @@ </LinearLayout> + <Button android:id="@+id/button_alert_dialog" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/button_alert_dialog_text" + android:textSize="32dip" + /> + </LinearLayout> + + <LinearLayout + android:layout_width="600dip" + android:layout_height="128dip" + android:layout_gravity="center_vertical" + android:orientation="horizontal" + style="@android:style/Widget.Holo.Spinner" + > + <LinearLayout + android:layout_width="0dip" + android:layout_weight="1" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:orientation="vertical" + > + <TextView + android:id="@+id/spinner_line_1" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:textSize="16dip" + android:singleLine="true" + android:ellipsize="end" + android:gravity="left|center_vertical" + android:text="@string/button_text" + /> + </LinearLayout> </LinearLayout> -</FrameLayout>
\ No newline at end of file +</FrameLayout> diff --git a/tests/BiDiTests/res/layout/canvas2.xml b/tests/BiDiTests/res/layout/canvas2.xml new file mode 100644 index 0000000..b3e038f --- /dev/null +++ b/tests/BiDiTests/res/layout/canvas2.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/canvas2" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <LinearLayout + xmlns:local="http://schemas.android.com/apk/res/com.android.bidi" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + <TextView + android:text="@string/ltr" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/ltr" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + <TextView + android:text="@string/rtl" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content"/> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/rtl" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + <TextView + android:text="@string/composing" + android:textSize="40dip" + android:gravity="center" + android:layout_width="fill_parent" + android:layout_height="wrap_content"/> + + <com.android.bidi.BiDiTestViewDrawText + local:text="@string/composing" + android:layout_width="fill_parent" + android:layout_height="64dp" /> + + </LinearLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/layout/gallery_ltr.xml b/tests/BiDiTests/res/layout/gallery_ltr.xml new file mode 100644 index 0000000..d0e4168 --- /dev/null +++ b/tests/BiDiTests/res/layout/gallery_ltr.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/gallery_ltr" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="ltr"> + + <Gallery + android:id="@+id/galleryview" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:spacing="10dip" + /> + +</FrameLayout> diff --git a/tests/BiDiTests/res/layout/gallery_rtl.xml b/tests/BiDiTests/res/layout/gallery_rtl.xml new file mode 100644 index 0000000..c5c2f5c --- /dev/null +++ b/tests/BiDiTests/res/layout/gallery_rtl.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/gallery_rtl" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="rtl"> + + <Gallery + android:id="@+id/galleryview" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:spacing="10dip" + /> + +</FrameLayout> diff --git a/tests/BiDiTests/res/values/attrs.xml b/tests/BiDiTests/res/values/attrs.xml new file mode 100644 index 0000000..7f8a1d8 --- /dev/null +++ b/tests/BiDiTests/res/values/attrs.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <declare-styleable name="DrawTextTestView"> + <attr name="size" format="dimension" /> + <attr name="color" format="color" /> + <attr name="text" format="string" /> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml index 9a486c1..1f6be7f 100644 --- a/tests/BiDiTests/res/values/strings.xml +++ b/tests/BiDiTests/res/values/strings.xml @@ -23,6 +23,7 @@ <string name="button_left_text">Left</string> <string name="button_before_text">Start</string> <string name="button_requestlayout_text">Request Layout</string> + <string name="button_alert_dialog_text">AlertDialog</string> <string name="textview_text">This is a text for a TextView</string> <string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string> <string name="normal_text">Normal String</string> @@ -41,5 +42,8 @@ <string name="textview_hebrew_text">םמab?!</string> <string name="textview_latin_text">abםמ?!</string> <string name="textview_multiline_text">םמ?!\nab?!\n?!</string> + <string name="ltr">Left to right text"</string> + <string name="rtl">"والحق أن تترك ونص"</string> + <string name="composing">"\u0644\u0627"</string> </resources> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index 7002c41..b45b98f 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -102,6 +102,7 @@ public class BiDiTestActivity extends Activity { addItem(result, "Basic", BiDiTestBasic.class, R.id.basic); addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas); + addItem(result, "Canvas2", BiDiTestCanvas2.class, R.id.canvas2); addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr); addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl); @@ -136,6 +137,8 @@ public class BiDiTestActivity extends Activity { addItem(result, "TextView Drawables LTR", BiDiTestTextViewDrawablesLtr.class, R.id.textview_drawables_ltr); addItem(result, "TextView Drawables RTL", BiDiTestTextViewDrawablesRtl.class, R.id.textview_drawables_rtl); + addItem(result, "Gallery LTR", BiDiTestGalleryLtr.class, R.id.gallery_ltr); + addItem(result, "Gallery RTL", BiDiTestGalleryRtl.class, R.id.gallery_rtl); return result; } @@ -146,4 +149,4 @@ public class BiDiTestActivity extends Activity { inflater.inflate(R.menu.main_menu, menu); return true; } -}
\ No newline at end of file +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestBasic.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestBasic.java index 9b3918d..f0b7438 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestBasic.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestBasic.java @@ -16,17 +16,42 @@ package com.android.bidi; +import android.app.AlertDialog; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; public class BiDiTestBasic extends Fragment { - + + private View currentView; + private Button alertDialogButton; + private String[] items = {"This is a very very very very very very very very very very very long Item1", "Item2"}; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.basic, container, false); + currentView = inflater.inflate(R.layout.basic, container, false); + return currentView; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + alertDialogButton = (Button) currentView.findViewById(R.id.button_alert_dialog); + alertDialogButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + showDialog(); + } + }); + } + + private void showDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(currentView.getContext()); + builder.setSingleChoiceItems(items, 0, null); + builder.show(); } } diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java new file mode 100644 index 0000000..b801f0e --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java @@ -0,0 +1,36 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.SeekBar; + +import static com.android.bidi.BiDiTestConstants.FONT_MAX_SIZE; +import static com.android.bidi.BiDiTestConstants.FONT_MIN_SIZE; + +public class BiDiTestCanvas2 extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.canvas2, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java new file mode 100644 index 0000000..adc17e1 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryImages.java @@ -0,0 +1,68 @@ +/* + * 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.bidi; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; + +public class BiDiTestGalleryImages extends BaseAdapter { + int mGalleryItemBackground; + private Context mContext; + + private Integer[] mImageIds = { + R.drawable.alphabet_a, + R.drawable.alphabet_b, + R.drawable.alphabet_c, + R.drawable.alphabet_d, + R.drawable.alphabet_e, + R.drawable.alphabet_f, + R.drawable.alphabet_g, + R.drawable.alphabet_h, + R.drawable.alphabet_i, + R.drawable.alphabet_j, + }; + + public BiDiTestGalleryImages(Context c) { + mContext = c; + } + + @Override + public int getCount() { + return mImageIds.length; + } + + @Override + public Object getItem(int position) { + return position; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ImageView i = new ImageView(mContext); + i.setImageResource(mImageIds[position]); + i.setScaleType(ScaleType.CENTER_INSIDE); + return i; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java new file mode 100644 index 0000000..fa86b1a --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryLtr.java @@ -0,0 +1,35 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Gallery; + +public class BiDiTestGalleryLtr extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.gallery_ltr, container, false); + Gallery g = (Gallery) v.findViewById(R.id.galleryview); + g.setAdapter(new BiDiTestGalleryImages(this.getActivity().getBaseContext())); + return v; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java new file mode 100644 index 0000000..4cef658 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGalleryRtl.java @@ -0,0 +1,35 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Gallery; + +public class BiDiTestGalleryRtl extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.gallery_rtl, container, false); + Gallery g = (Gallery) v.findViewById(R.id.galleryview); + g.setAdapter(new BiDiTestGalleryImages(this.getActivity().getBaseContext())); + return v; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java index 4f17e52..0126dea 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java @@ -21,7 +21,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; -import android.graphics.Typeface; +import android.text.TextPaint; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -37,7 +37,6 @@ public class BiDiTestView extends View { private static final float DEFAULT_ITALIC_SKEW_X = -0.25f; - private Paint paint = new Paint(); private Rect rect = new Rect(); private String NORMAL_TEXT; @@ -51,8 +50,7 @@ public class BiDiTestView extends View { private String CHINESE_TEXT; private String MIXED_TEXT_1; private String HEBREW_TEXT; - - private Typeface typeface; + private String RTL_TEXT; private int currentTextSize; @@ -83,9 +81,7 @@ public class BiDiTestView extends View { CHINESE_TEXT = context.getString(R.string.chinese_text); MIXED_TEXT_1 = context.getString(R.string.mixed_text_1); HEBREW_TEXT = context.getString(R.string.hebrew_text); - - typeface = paint.getTypeface(); - paint.setAntiAlias(true); + RTL_TEXT = context.getString(R.string.rtl); } public void setCurrentTextSize(int size) { @@ -95,54 +91,56 @@ public class BiDiTestView extends View { @Override public void onDraw(Canvas canvas) { - drawInsideRect(canvas, Color.BLACK); + drawInsideRect(canvas, new Paint(), Color.BLACK); int deltaX = 0; deltaX = testString(canvas, NORMAL_TEXT, ORIGIN, ORIGIN, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, ITALIC_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, true, false, Paint.DIRECTION_LTR, currentTextSize); + true, false, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, BOLD_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, false, true, Paint.DIRECTION_LTR, currentTextSize); + false, true, Paint.DIRECTION_LTR, currentTextSize); deltaX += testString(canvas, BOLD_ITALIC_TEXT, ORIGIN + deltaX, ORIGIN, - paint, typeface, true, true, Paint.DIRECTION_LTR, currentTextSize); + true, true, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT, ORIGIN, ORIGIN + 2 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT_2, ORIGIN, ORIGIN + 4 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test with a long string deltaX = testString(canvas, NORMAL_LONG_TEXT_3, ORIGIN, ORIGIN + 6 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Arabic ligature deltaX = testString(canvas, ARABIC_TEXT, ORIGIN, ORIGIN + 8 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_RTL, currentTextSize); + false, false, Paint.DIRECTION_RTL, currentTextSize); // Test Chinese deltaX = testString(canvas, CHINESE_TEXT, ORIGIN, ORIGIN + 10 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Mixed (English and Arabic) deltaX = testString(canvas, MIXED_TEXT_1, ORIGIN, ORIGIN + 12 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_LTR, currentTextSize); + false, false, Paint.DIRECTION_LTR, currentTextSize); // Test Hebrew - deltaX = testString(canvas, HEBREW_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize, - paint, typeface, false, false, Paint.DIRECTION_RTL, currentTextSize); + deltaX = testString(canvas, RTL_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize, + false, false, Paint.DIRECTION_RTL, currentTextSize); } - private int testString(Canvas canvas, String text, int x, int y, Paint paint, Typeface typeface, + private int testString(Canvas canvas, String text, int x, int y, boolean isItalic, boolean isBold, int dir, int textSize) { - paint.setTypeface(typeface); + + TextPaint paint = new TextPaint(); + paint.setAntiAlias(true); // Set paint properties boolean oldFakeBold = paint.isFakeBoldText(); @@ -153,9 +151,9 @@ public class BiDiTestView extends View { paint.setTextSkewX(DEFAULT_ITALIC_SKEW_X); } - Log.v(TAG, "START -- drawTextWithCanvasDrawText"); - drawTextWithCanvasDrawText(text, canvas, x, y, textSize, Color.WHITE, dir); - Log.v(TAG, "END -- drawTextWithCanvasDrawText"); + paint.setTextSize(textSize); + paint.setColor(Color.WHITE); + canvas.drawText(text, x, y, paint); int length = text.length(); float[] advances = new float[length]; @@ -167,17 +165,6 @@ public class BiDiTestView extends View { logAdvances(text, textWidthHB, textWidthICU, advances); drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN); - paint.setColor(Color.WHITE); -// char[] glyphs = new char[2*length]; -// int count = getGlyphs(text, glyphs, dir); -// -// logGlypths(glyphs, count); -// drawTextWithDrawGlyph(canvas, glyphs, count, x, y + currentTextSize); - - Log.v(TAG, "START -- drawTextWithGlyphs"); - drawTextWithGlyphs(canvas, text, x, y + currentTextSize, dir); - Log.v(TAG, "END -- drawTextWithGlyphs"); - // Restore old paint properties paint.setFakeBoldText(oldFakeBold); paint.setTextSkewX(oldTextSkewX); @@ -190,27 +177,7 @@ public class BiDiTestView extends View { paint.setBidiFlags(dir); } - private void drawTextWithDrawGlyph(Canvas canvas, char[] glyphs, int count, int x, int y) { - canvas.drawGlyphs(glyphs, 0, count, x, y, paint); - } - - private void drawTextWithGlyphs(Canvas canvas, String text, int x, int y, int dir) { - setPaintDir(paint, dir); - canvas.drawTextWithGlyphs(text, x, y, paint); - } - - private void logGlypths(char[] glyphs, int count) { - Log.v(TAG, "GlyphIds - count=" + count); - for (int n = 0; n < count; n++) { - Log.v(TAG, "GlyphIds - Id[" + n + "]="+ (int)glyphs[n]); - } - } - - private int getGlyphs(String text, char[] glyphs, int dir) { - return paint.getTextGlypths(text, 0, text.length(), 0, text.length(), dir, glyphs); - } - - private void drawInsideRect(Canvas canvas, int color) { + private void drawInsideRect(Canvas canvas, Paint paint, int color) { paint.setColor(color); int width = getWidth(); int height = getHeight(); @@ -218,16 +185,9 @@ public class BiDiTestView extends View { canvas.drawRect(rect, paint); } - private void drawTextWithCanvasDrawText(String text, Canvas canvas, - float x, float y, float textSize, int color, int dir) { - setPaintDir(paint, dir); - paint.setColor(color); - paint.setTextSize(textSize); - canvas.drawText(text, x, y, paint); - } - private void drawMetricsAroundText(Canvas canvas, int x, int y, float textWidthHB, float textWidthICU, int textSize, int color, int colorICU) { + Paint paint = new Paint(); paint.setColor(color); canvas.drawLine(x, y - textSize, x, y + 8, paint); canvas.drawLine(x, y + 8, x + textWidthHB, y + 8, paint); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java new file mode 100644 index 0000000..dfdb807 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java @@ -0,0 +1,66 @@ +/* + * 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.bidi; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint.Align; +import android.text.TextPaint; +import android.util.AttributeSet; +import android.view.View; + +public class BiDiTestViewDrawText extends View { + private float mSize; + private int mColor; + private String mText; + + public BiDiTestViewDrawText(Context context) { + this(context, null); + } + + public BiDiTestViewDrawText(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BiDiTestViewDrawText(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + final TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.DrawTextTestView, defStyle, 0); + mSize = a.getDimension(R.styleable.DrawTextTestView_size, 40.0f); + mColor = a.getColor(R.styleable.DrawTextTestView_color, Color.YELLOW); + final CharSequence text = a.getText(R.styleable.DrawTextTestView_text); + mText = (text != null) ? text.toString() : "(empty)"; + a.recycle(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + final int width = getWidth(); + final int height = getHeight(); + + final TextPaint paint = new TextPaint(); + paint.setTextSize(mSize); + paint.setColor(mColor); + paint.setTextAlign(Align.CENTER); + + canvas.drawText(mText, width / 2, height * 2 / 3, paint); + } +}
\ No newline at end of file diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java index af5006f..38a85a3 100644 --- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java +++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java @@ -95,9 +95,7 @@ public class Activity2 extends Activity { } { Space v = new Space(context); - { - vg.addView(v, new LayoutParams(row5, col3)); - } + vg.addView(v, new LayoutParams(row5, col3)); } { Button v = new Button(context); diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 32a6a65..9fcd05a 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -94,6 +94,15 @@ </activity> <activity + android:name="CanvasTextureViewActivity" + android:label="_CanvasTextureView"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="GLTextureViewActivity" android:label="_TextureViewGL"> <intent-filter> diff --git a/tests/HwAccelerationTest/res/layout/list_activity.xml b/tests/HwAccelerationTest/res/layout/list_activity.xml index 6bba370..1a5d3d9 100644 --- a/tests/HwAccelerationTest/res/layout/list_activity.xml +++ b/tests/HwAccelerationTest/res/layout/list_activity.xml @@ -30,8 +30,10 @@ android:layout_height="wrap_content" android:layout_marginLeft="10dip" android:layout_marginRight="3dip" + + android:onClick="startProfiling" - android:text="Add" /> + android:text="Start" /> <Button android:layout_width="0dip" @@ -39,8 +41,10 @@ android:layout_height="wrap_content" android:layout_marginLeft="3dip" android:layout_marginRight="10dip" + + android:onClick="stopProfiling" - android:text="Remove" /> + android:text="Stop" /> </LinearLayout> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java new file mode 100644 index 0000000..81c22b8 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java @@ -0,0 +1,120 @@ +/* + * 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.test.hwui; + +import android.app.Activity; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.SurfaceTexture; +import android.os.Bundle; +import android.view.Gravity; +import android.view.TextureView; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class CanvasTextureViewActivity extends Activity + implements TextureView.SurfaceTextureListener { + private TextureView mTextureView; + private CanvasTextureViewActivity.RenderingThread mThread; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mTextureView = new TextureView(this); + mTextureView.setSurfaceTextureListener(this); + mTextureView.setOpaque(false); + + content.addView(mTextureView, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER)); + setContentView(content); + } + + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + mThread = new RenderingThread(mTextureView); + mThread.start(); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + // Ignored + } + + @Override + public void onSurfaceTextureDestroyed(SurfaceTexture surface) { + if (mThread != null) mThread.stopRendering(); + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + // Ignored + } + + private static class RenderingThread extends Thread { + private final TextureView mSurface; + private volatile boolean mRunning = true; + + public RenderingThread(TextureView surface) { + mSurface = surface; + } + + @Override + public void run() { + float x = 0.0f; + float y = 0.0f; + float speedX = 5.0f; + float speedY = 3.0f; + + Paint paint = new Paint(); + paint.setColor(0xff00ff00); + + while (mRunning && !Thread.interrupted()) { + final Canvas canvas = mSurface.lockCanvas(null); + try { + canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); + canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint); + } finally { + mSurface.unlockCanvasAndPost(canvas); + } + + if (x + 20.0f + speedX >= mSurface.getWidth() || x + speedX <= 0.0f) { + speedX = -speedX; + } + if (y + 20.0f + speedY >= mSurface.getHeight() || y + speedY <= 0.0f) { + speedY = -speedY; + } + + x += speedX; + y += speedY; + + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // Interrupted + } + } + } + + void stopRendering() { + interrupt(); + mRunning = false; + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java index 8fd4f6b..1493ab9 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java @@ -20,15 +20,19 @@ import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.os.Bundle; +import android.os.Environment; import android.util.DisplayMetrics; import android.view.ContextMenu; import android.view.View; +import android.view.ViewDebug; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; +import java.io.File; + @SuppressWarnings({"UnusedDeclaration"}) public class ListActivity extends Activity { private static final String[] DATA_LIST = { @@ -87,6 +91,15 @@ public class ListActivity extends Activity { registerForContextMenu(list); } + + public void startProfiling(View v) { + ViewDebug.startLooperProfiling(new File(Environment.getExternalStorageDirectory(), + "looper.trace")); + } + + public void stopProfiling(View v) { + ViewDebug.stopLooperProfiling(); + } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { diff --git a/tests/TileBenchmark/Android.mk b/tests/TileBenchmark/Android.mk new file mode 100644 index 0000000..430f0f1 --- /dev/null +++ b/tests/TileBenchmark/Android.mk @@ -0,0 +1,32 @@ +# 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. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := TileBenchmark + +include $(BUILD_PACKAGE) + +################################################## +include $(CLEAR_VARS) + +include $(BUILD_MULTI_PREBUILT) + +# Use the folloing include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/TileBenchmark/AndroidManifest.xml b/tests/TileBenchmark/AndroidManifest.xml new file mode 100644 index 0000000..663cc0d --- /dev/null +++ b/tests/TileBenchmark/AndroidManifest.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + android:versionCode="1" + android:versionName="1.0" package="com.test.tilebenchmark"> + <uses-permission android:name="android.permission.INTERNET"/> + <application android:icon="@drawable/icon" + android:label="@string/app_name" + android:hardwareAccelerated="true"> + <activity android:name=".ProfileActivity" + android:label="@string/profile_activity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name=".PlaybackActivity" + android:label="@string/playback_activity"> + </activity> + </application> +</manifest> diff --git a/tests/TileBenchmark/res/drawable-hdpi/icon.png b/tests/TileBenchmark/res/drawable-hdpi/icon.png Binary files differnew file mode 100644 index 0000000..8074c4c --- /dev/null +++ b/tests/TileBenchmark/res/drawable-hdpi/icon.png diff --git a/tests/TileBenchmark/res/drawable-ldpi/icon.png b/tests/TileBenchmark/res/drawable-ldpi/icon.png Binary files differnew file mode 100644 index 0000000..1095584 --- /dev/null +++ b/tests/TileBenchmark/res/drawable-ldpi/icon.png diff --git a/tests/TileBenchmark/res/drawable-mdpi/icon.png b/tests/TileBenchmark/res/drawable-mdpi/icon.png Binary files differnew file mode 100644 index 0000000..a07c69f --- /dev/null +++ b/tests/TileBenchmark/res/drawable-mdpi/icon.png diff --git a/tests/TileBenchmark/res/layout/main.xml b/tests/TileBenchmark/res/layout/main.xml new file mode 100644 index 0000000..4a81da6 --- /dev/null +++ b/tests/TileBenchmark/res/layout/main.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <LinearLayout + android:id="@+id/top" + android:layout_width="match_parent" + android:layout_height="wrap_content" + > + <Button + android:id="@+id/inspect" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/inspect_log" + /> + <Spinner + android:id="@+id/velocity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:prompt="@string/desired_scroll_velocity" + /> + <EditText + android:id="@+id/url" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:inputType="textUri" + android:imeOptions="actionGo" + android:layout_weight="1" + /> + </LinearLayout> + <com.test.tilebenchmark.ProfiledWebView + android:id="@+id/web" + android:layout_width="match_parent" + android:layout_height="match_parent" + /> +</LinearLayout> diff --git a/tests/TileBenchmark/res/layout/playback.xml b/tests/TileBenchmark/res/layout/playback.xml new file mode 100644 index 0000000..aa1c8a4 --- /dev/null +++ b/tests/TileBenchmark/res/layout/playback.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <LinearLayout + android:id="@+id/top" + android:layout_width="match_parent" + android:layout_height="wrap_content" + > + <Button + android:id="@+id/backward" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/backward" + /> + <TextView + android:id="@+id/frame_display" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceLarge" + android:layout_weight="1" + /> + <Button + android:id="@+id/forward" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/forward" + /> + <SeekBar + android:id="@+id/seek_bar" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="10" + /> + </LinearLayout> + <com.test.tilebenchmark.PlaybackView + android:id="@+id/playback" + android:layout_width="match_parent" + android:layout_height="match_parent" + /> +</LinearLayout> diff --git a/tests/TileBenchmark/res/values/colors.xml b/tests/TileBenchmark/res/values/colors.xml new file mode 100644 index 0000000..3958083 --- /dev/null +++ b/tests/TileBenchmark/res/values/colors.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<resources> + <!-- The color of tiles with valid textures --> + <color name="ready_tile">#ff4ac230</color> + <!-- The color of tiles with stale / invalid textures --> + <color name="unready_tile">#ff744400</color> + <!-- Background color for logged URLs --> + <color name="finished_url">#ff004000</color> + <!-- Background color for URLs with logging in progress --> + <color name="unfinished_url">#ff400000</color> +</resources> diff --git a/tests/TileBenchmark/res/values/strings.xml b/tests/TileBenchmark/res/values/strings.xml new file mode 100644 index 0000000..f70ee2c --- /dev/null +++ b/tests/TileBenchmark/res/values/strings.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<resources> + <!-- Button, steps back a single frame [CHAR LIMIT=15] --> + <string name="backward">Backward</string> + <!-- Button, steps forward a single frame [CHAR LIMIT=15] --> + <string name="forward">Forward</string> + <!-- The name of the application [CHAR LIMIT=20] --> + <string name="app_name">TileBenchmark</string> + <!-- name of the auto-scroller / tile logger activity [CHAR LIMIT=100] --> + <string name="profile_activity">Webview Profiler</string> + <!-- name of the tile log playback activity [CHAR LIMIT=100] --> + <string name="playback_activity">Webview Tile Playback</string> + <!-- Button, loads another tile log [CHAR LIMIT=30] --> + <string name="loadbutton">Load</string> + <!-- Button, opens the playback activity [CHAR LIMIT=20] --> + <string name="inspect_log">Inspect Log</string> + <!-- The speed of auto-scrolling [CHAR LIMIT=30] --> + <string name="desired_scroll_velocity">Choose Scroll Velocity</string> + <!-- Pixels moved per frame [CHAR LIMIT=10] --> + <string-array name="velocity_array"> + <item>1</item> + <item>25</item> + <item>50</item> + <item>100</item> + <item>200</item> + <item>400</item> + </string-array> + <!-- 25th percentile - 25% of frames fall below this value [CHAR LIMIT=12] + --> + <string name="percentile_25">25%ile</string> + <!-- 50th percentile - 50% of frames fall below this value (aka median) + [CHAR LIMIT=12] --> + <string name="percentile_50">median</string> + <!-- 75th percentile - 75% of frames fall below this value [CHAR LIMIT=12] + --> + <string name="percentile_75">75%ile</string> + <!-- Frame rate [CHAR LIMIT=15] --> + <string name="frames_per_second">Frames/sec</string> + <!-- Portion of viewport covered by good tiles [CHAR LIMIT=15] --> + <string name="viewport_coverage">Coverage</string> + <!-- Format string for stat value overlay [CHAR LIMIT=15] --> + <string name="format_stat">%4.4f</string> + <!-- Format string for displaying aggregate stats+values (nr of valid tiles, + etc.) [CHAR LIMIT=20] --> + <string name="format_stat_name">%1$9s %2$3d</string> + <!-- Text hovering over canvas, number of tiles ready [CHAR LIMIT=15] --> + <string name="ready_tiles">Ready Tiles</string> + <!-- Text hovering over canvas, number tiles not ready [CHAR LIMIT=15] --> + <string name="unready_tiles">Unready Tiles</string> + <!-- Text hovering over canvas, number of tiles that haven't been + allocated to a place on the page [CHAR LIMIT=15] --> + <string name="unplaced_tiles">Unplaced Tiles</string> +</resources> diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java new file mode 100644 index 0000000..5130f5d --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java @@ -0,0 +1,188 @@ +/* + * 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.test.tilebenchmark; + +import android.app.Activity; +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + +/** + * Interface for playing back WebView tile rendering status. Draws viewport and + * states of tiles and statistics for off-line analysis. + */ +public class PlaybackActivity extends Activity { + private static final float SCROLL_SCALER = 0.125f; + + PlaybackView mPlaybackView; + SeekBar mSeekBar; + Button mForward; + Button mBackward; + TextView mFrameDisplay; + + private int mFrame = -1; + private int mFrameMax; + + private class TouchFrameChangeListener extends SimpleOnGestureListener { + float mDist = 0; + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, + float distanceX, float distanceY) { + // aggregate scrolls so that small ones can add up + mDist += distanceY * SCROLL_SCALER; + int intComponent = (int) Math.floor(Math.abs(mDist)); + if (intComponent >= 1) { + int scrollDist = (mDist > 0) ? intComponent : -intComponent; + setFrame(null, mFrame + scrollDist); + mDist -= scrollDist; + } + return super.onScroll(e1, e2, distanceX, distanceY); + } + }; + + private class SeekFrameChangeListener implements OnSeekBarChangeListener { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, + boolean fromUser) { + setFrame(seekBar, progress); + } + }; + + private class LoadFileTask extends AsyncTask<String, Void, TileData[][]> { + @Override + protected TileData[][] doInBackground(String... params) { + TileData[][] data = null; + try { + FileInputStream fis = openFileInput(params[0]); + ObjectInputStream in = new ObjectInputStream(fis); + data = (TileData[][]) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + return data; + } + + @Override + protected void onPostExecute(TileData data[][]) { + if (data == null) { + data = genTestPattern(); + } + mPlaybackView.setData(data); + + mFrameMax = data.length - 1; + mSeekBar.setMax(mFrameMax); + + setFrame(null, 0); + } + } + + private void setFrame(View changer, int f) { + if (f < 0) { + f = 0; + } else if (f > mFrameMax) { + f = mFrameMax; + } + + if (mFrame == f) { + return; + } + + mFrame = f; + mForward.setEnabled(mFrame != mFrameMax); + mBackward.setEnabled(mFrame != 0); + if (changer != mSeekBar) { + mSeekBar.setProgress(mFrame); + } + mFrameDisplay.setText(Integer.toString(mFrame)); + mPlaybackView.setFrame(mFrame); + }; + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.playback); + + mPlaybackView = (PlaybackView) findViewById(R.id.playback); + mSeekBar = (SeekBar) findViewById(R.id.seek_bar); + mForward = (Button) findViewById(R.id.forward); + mBackward = (Button) findViewById(R.id.backward); + mFrameDisplay = (TextView) findViewById(R.id.frame_display); + + mForward.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + setFrame(v, mFrame + 1); + } + }); + + mBackward.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + setFrame(v, mFrame - 1); + } + }); + + mSeekBar.setOnSeekBarChangeListener(new SeekFrameChangeListener()); + + mPlaybackView.setOnGestureListener(new TouchFrameChangeListener()); + + new LoadFileTask().execute(ProfileActivity.TEMP_FILENAME); + } + + private TileData[][] genTestPattern() { + final int XMAX = 5; + final int FRAMEMAX = 99; + + TileData example[][] = new TileData[FRAMEMAX][]; + for (int frame = 0; frame < FRAMEMAX; frame++) { + int numTiles = frame + 10; + + example[frame] = new TileData[numTiles]; + for (int t = 0; t < numTiles; t++) { + int x = t % XMAX; + int y = t / XMAX; + boolean isReady = y * 10 < frame; + example[frame][t] = new TileData(x, y, isReady, 0); + } + } + return example; + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java new file mode 100644 index 0000000..db4a341 --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java @@ -0,0 +1,264 @@ +/* + * 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.test.tilebenchmark; + +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.ShapeDrawable; +import android.os.Bundle; + +import java.util.ArrayList; +import java.util.Arrays; + +public class PlaybackGraphs { + private static final int BAR_WIDTH = PlaybackView.TILEX * 3; + private static final float CANVAS_SCALE = 0.2f; + private static final double IDEAL_FRAMES = 60; + private static final int LABELOFFSET = 100; + private static Paint whiteLabels; + + private static double viewportCoverage(int l, int b, int r, int t, + int tileIndexX, + int tileIndexY) { + if (tileIndexX * PlaybackView.TILEX < r + && (tileIndexX + 1) * PlaybackView.TILEX >= l + && tileIndexY * PlaybackView.TILEY < t + && (tileIndexY + 1) * PlaybackView.TILEY >= b) { + return 1.0f; + } + return 0.0f; + } + + private interface MetricGen { + public double getValue(TileData[] frame); + + public double getMax(); + + public int getLabelId(); + }; + + private static MetricGen[] Metrics = new MetricGen[] { + new MetricGen() { + // framerate graph + @Override + public double getValue(TileData[] frame) { + int renderTimeUS = frame[0].level; + return 1.0e6f / renderTimeUS; + } + + @Override + public double getMax() { + return IDEAL_FRAMES; + } + + @Override + public int getLabelId() { + return R.string.frames_per_second; + } + }, new MetricGen() { + // coverage graph + @Override + public double getValue(TileData[] frame) { + int l = frame[0].x, b = frame[0].y; + int r = frame[1].x, t = frame[1].y; + double total = 0, totalCount = 0; + for (int tileID = 2; tileID < frame.length; tileID++) { + TileData data = frame[tileID]; + double coverage = viewportCoverage(l, b, r, t, data.x, + data.y); + total += coverage * (data.isReady ? 1 : 0); + totalCount += coverage; + } + if (totalCount == 0) { + return -1; + } + return total / totalCount; + } + + @Override + public double getMax() { + return 1; + } + + @Override + public int getLabelId() { + return R.string.viewport_coverage; + } + } + }; + + private interface StatGen { + public double getValue(double sortedValues[]); + + public int getLabelId(); + } + + public static double getPercentile(double sortedValues[], double ratioAbove) { + double index = ratioAbove * (sortedValues.length - 1); + int intIndex = (int) Math.floor(index); + if (index == intIndex) { + return sortedValues[intIndex]; + } + double alpha = index - intIndex; + return sortedValues[intIndex] * (1 - alpha) + + sortedValues[intIndex + 1] * (alpha); + } + + private static StatGen[] Stats = new StatGen[] { + new StatGen() { + @Override + public double getValue(double[] sortedValues) { + return getPercentile(sortedValues, 0.25); + } + + @Override + public int getLabelId() { + return R.string.percentile_25; + } + }, new StatGen() { + @Override + public double getValue(double[] sortedValues) { + return getPercentile(sortedValues, 0.5); + } + + @Override + public int getLabelId() { + return R.string.percentile_50; + } + }, new StatGen() { + @Override + public double getValue(double[] sortedValues) { + return getPercentile(sortedValues, 0.75); + } + + @Override + public int getLabelId() { + return R.string.percentile_75; + } + }, + }; + + public PlaybackGraphs() { + whiteLabels = new Paint(); + whiteLabels.setColor(Color.WHITE); + whiteLabels.setTextSize(PlaybackView.TILEY / 3); + } + + private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>(); + private double[][] mStats = new double[Metrics.length][Stats.length]; + + public void setData(TileData[][] tileProfilingData) { + mShapes.clear(); + double metricValues[] = new double[tileProfilingData.length]; + + if (tileProfilingData.length == 0) { + return; + } + + for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { + // create graph out of rectangles, one per frame + int lastBar = 0; + for (int frameIndex = 0; frameIndex < tileProfilingData.length; frameIndex++) { + TileData frame[] = tileProfilingData[frameIndex]; + int newBar = (frame[0].y + frame[1].y) / 2; + + MetricGen s = Metrics[metricIndex]; + double absoluteValue = s.getValue(frame); + double relativeValue = absoluteValue / s.getMax(); + int rightPos = (int) (-BAR_WIDTH * metricIndex); + int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue)); + + ShapeDrawable graphBar = new ShapeDrawable(); + graphBar.getPaint().setColor(Color.BLUE); + graphBar.setBounds(leftPos, lastBar, rightPos, newBar); + + mShapes.add(graphBar); + metricValues[frameIndex] = absoluteValue; + lastBar = newBar; + } + + // store aggregate statistics per metric (median, and similar) + Arrays.sort(metricValues); + for (int statIndex = 0; statIndex < Stats.length; statIndex++) { + mStats[metricIndex][statIndex] = Stats[statIndex] + .getValue(metricValues); + } + } + } + + public void drawVerticalShiftedShapes(Canvas canvas, + ArrayList<ShapeDrawable> shapes) { + // Shapes drawn here are drawn relative to the viewRect + Rect viewRect = shapes.get(shapes.size() - 1).getBounds(); + canvas.translate(0, 5 * PlaybackView.TILEY - viewRect.top); + + for (ShapeDrawable shape : mShapes) { + shape.draw(canvas); + } + for (ShapeDrawable shape : shapes) { + shape.draw(canvas); + } + } + + public void draw(Canvas canvas, ArrayList<ShapeDrawable> shapes, + String[] strings, Resources resources) { + canvas.scale(CANVAS_SCALE, CANVAS_SCALE); + + canvas.translate(BAR_WIDTH * Metrics.length, 0); + + canvas.save(); + drawVerticalShiftedShapes(canvas, shapes); + canvas.restore(); + + for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { + String label = resources.getString( + Metrics[metricIndex].getLabelId()); + int xPos = (metricIndex + 1) * -BAR_WIDTH; + int yPos = LABELOFFSET; + canvas.drawText(label, xPos, yPos, whiteLabels); + for (int statIndex = 0; statIndex < Stats.length; statIndex++) { + label = resources.getString(R.string.format_stat, mStats[metricIndex][statIndex]); + yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILEY / 2; + canvas.drawText(label, xPos, yPos, whiteLabels); + } + } + for (int stringIndex = 0; stringIndex < strings.length; stringIndex++) { + int yPos = LABELOFFSET + stringIndex * PlaybackView.TILEY / 2; + canvas.drawText(strings[stringIndex], 0, yPos, whiteLabels); + } + } + + public Bundle getStatBundle(Resources resources) { + Bundle b = new Bundle(); + + for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { + for (int statIndex = 0; statIndex < Stats.length; statIndex++) { + String metricLabel = resources.getString( + Metrics[metricIndex].getLabelId()); + String statLabel = resources.getString( + Stats[statIndex].getLabelId()); + double value = mStats[metricIndex][statIndex]; + b.putDouble(metricLabel + " " + statLabel, value); + } + } + + return b; + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java new file mode 100644 index 0000000..f104eac --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java @@ -0,0 +1,159 @@ +/* + * 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.test.tilebenchmark; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.ShapeDrawable; +import android.util.AttributeSet; +import android.view.GestureDetector; +import android.view.GestureDetector.OnGestureListener; +import android.view.MotionEvent; +import android.view.View; + +import java.util.ArrayList; + +public class PlaybackView extends View { + public static final int TILEX = 300; + public static final int TILEY = 300; + + private Paint levelPaint = null, coordPaint = null, goldPaint = null; + private PlaybackGraphs mGraphs; + + private ArrayList<ShapeDrawable> mTempShapes = new ArrayList<ShapeDrawable>(); + private TileData mProfData[][] = null; + private GestureDetector mGestureDetector = null; + private String mRenderStrings[] = new String[3]; + + private class TileDrawable extends ShapeDrawable { + TileData tile; + + public TileDrawable(TileData t) { + int tileColorId = t.isReady ? R.color.ready_tile + : R.color.unready_tile; + getPaint().setColor(getResources().getColor(tileColorId)); + + setBounds(t.x * TILEX, t.y * TILEY, (t.x + 1) * TILEX, (t.y + 1) + * TILEY); + this.tile = t; + } + + @Override + public void draw(Canvas canvas) { + super.draw(canvas); + canvas.drawText(Integer.toString(tile.level), getBounds().left, + getBounds().bottom, levelPaint); + canvas.drawText(tile.x + "," + tile.y, getBounds().left, + ((getBounds().bottom + getBounds().top) / 2), coordPaint); + } + } + + public PlaybackView(Context context) { + super(context); + init(); + } + + public PlaybackView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public PlaybackView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + public void setOnGestureListener(OnGestureListener gl) { + mGestureDetector = new GestureDetector(getContext(), gl); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + mGestureDetector.onTouchEvent(event); + return true; + } + + private void init() { + levelPaint = new Paint(); + levelPaint.setColor(Color.WHITE); + levelPaint.setTextSize(TILEY / 2); + coordPaint = new Paint(); + coordPaint.setColor(Color.BLACK); + coordPaint.setTextSize(TILEY / 3); + goldPaint = new Paint(); + goldPaint.setColor(0xffa0e010); + mGraphs = new PlaybackGraphs(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (mTempShapes == null || mTempShapes.isEmpty()) { + return; + } + + mGraphs.draw(canvas, mTempShapes, mRenderStrings, getResources()); + } + + public int setFrame(int frame) { + if (mProfData == null || mProfData.length == 0) { + return 0; + } + + int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0; + mTempShapes.clear(); + + // draw actual tiles + for (int tileID = 2; tileID < mProfData[frame].length; tileID++) { + TileData t = mProfData[frame][tileID]; + mTempShapes.add(new TileDrawable(t)); + if (t.isReady) { + readyTiles++; + } else { + unreadyTiles++; + } + if (t.x < 0 || t.y < 0) { + unplacedTiles++; + } + } + mRenderStrings[0] = getResources().getString(R.string.format_stat_name, + getResources().getString(R.string.ready_tiles), readyTiles); + mRenderStrings[1] = getResources().getString(R.string.format_stat_name, + getResources().getString(R.string.unready_tiles), unreadyTiles); + mRenderStrings[2] = getResources().getString(R.string.format_stat_name, + getResources().getString(R.string.unplaced_tiles), unplacedTiles); + + // draw view rect (using first two TileData objects) + ShapeDrawable viewShape = new ShapeDrawable(); + viewShape.getPaint().setColor(0xff0000ff); + viewShape.setAlpha(64); + viewShape.setBounds(mProfData[frame][0].x, mProfData[frame][0].y, + mProfData[frame][1].x, mProfData[frame][1].y); + mTempShapes.add(viewShape); + this.invalidate(); + return frame; + } + + public void setData(TileData[][] tileProfilingData) { + mProfData = tileProfilingData; + + mGraphs.setData(mProfData); + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java new file mode 100644 index 0000000..23b6275 --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java @@ -0,0 +1,203 @@ +/* + * 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.test.tilebenchmark; + +import android.app.Activity; +import android.content.Intent; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.util.Pair; +import android.view.KeyEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.TextView.OnEditorActionListener; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +/** + * Interface for profiling the webview's scrolling, with simple controls on how + * to scroll, and what content to load. + */ +public class ProfileActivity extends Activity { + + public interface ProfileCallback { + public void profileCallback(TileData data[][]); + } + + public static final String TEMP_FILENAME = "profile.tiles"; + private static final int LOAD_TEST_DELAY = 2000; // nr of millis after load, + // before test + + Button mInspectButton; + Spinner mVelocitySpinner; + EditText mUrl; + ProfiledWebView mWeb; + ProfileCallback mCallback; + + private class VelocitySelectedListener implements OnItemSelectedListener { + @Override + public void onItemSelected(AdapterView<?> parent, View view, + int position, long id) { + String speedStr = parent.getItemAtPosition(position).toString(); + int speedInt = Integer.parseInt(speedStr); + mWeb.setAutoScrollSpeed(speedInt); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + } + } + + private class LoggingWebViewClient extends WebViewClient { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + return false; + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + mUrl.setText(url); + } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + view.requestFocus(); + new CountDownTimer(LOAD_TEST_DELAY, LOAD_TEST_DELAY) { + @Override + public void onTick(long millisUntilFinished) { + } + + @Override + public void onFinish() { + mWeb.startScrollTest(mCallback); + } + }.start(); + } + } + + private class StoreFileTask extends + AsyncTask<Pair<String, TileData[][]>, Void, Void> { + + @Override + protected Void doInBackground(Pair<String, TileData[][]>... params) { + try { + FileOutputStream fos = openFileOutput(params[0].first, + Context.MODE_PRIVATE); + ObjectOutputStream out = new ObjectOutputStream(fos); + out.writeObject(params[0].second); + out.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void v) { + mUrl.setBackgroundResource(R.color.finished_url); + } + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + mInspectButton = (Button) findViewById(R.id.inspect); + mVelocitySpinner = (Spinner) findViewById(R.id.velocity); + mUrl = (EditText) findViewById(R.id.url); + mWeb = (ProfiledWebView) findViewById(R.id.web); + mCallback = new ProfileCallback() { + @SuppressWarnings("unchecked") + @Override + public void profileCallback(TileData[][] data) { + new StoreFileTask().execute(new Pair<String, TileData[][]>(TEMP_FILENAME, data)); + } + }; + + // Inspect button (opens PlaybackActivity) + mInspectButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(ProfileActivity.this, + PlaybackActivity.class)); + } + }); + + // Velocity spinner + ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( + this, R.array.velocity_array, + android.R.layout.simple_spinner_item); + adapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + mVelocitySpinner.setAdapter(adapter); + mVelocitySpinner.setOnItemSelectedListener( + new VelocitySelectedListener()); + mVelocitySpinner.setSelection(3); + + // Custom profiling WebView + WebSettings settings = mWeb.getSettings(); + settings.setJavaScriptEnabled(true); + settings.setSupportZoom(true); + settings.setEnableSmoothTransition(true); + settings.setBuiltInZoomControls(true); + settings.setLoadWithOverviewMode(true); + mWeb.setWebViewClient(new LoggingWebViewClient()); + + // URL text entry + mUrl.setOnEditorActionListener(new OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, + KeyEvent event) { + String url = mUrl.getText().toString(); + mUrl.setBackgroundResource(R.color.unfinished_url); + mWeb.loadUrl(url); + mWeb.requestFocus(); + return true; + } + }); + } + + public void setCallback(ProfileCallback callback) { + mCallback = callback; + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) { + mWeb.goBack(); + return true; + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java new file mode 100644 index 0000000..6560624 --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java @@ -0,0 +1,106 @@ +/* + * 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.test.tilebenchmark; + +import android.content.Context; +import android.util.AttributeSet; +import android.webkit.WebView; + +import com.test.tilebenchmark.ProfileActivity.ProfileCallback; + +public class ProfiledWebView extends WebView { + private int mSpeed; + + private boolean isScrolling = false; + private ProfileCallback mCallback; + + public ProfiledWebView(Context context) { + super(context); + } + + public ProfiledWebView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ProfiledWebView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public ProfiledWebView(Context context, AttributeSet attrs, int defStyle, + boolean privateBrowsing) { + super(context, attrs, defStyle, privateBrowsing); + } + + @Override + protected void onDraw(android.graphics.Canvas canvas) { + if (isScrolling) { + if (canScrollVertically(1)) { + scrollBy(0, mSpeed); + } else { + stopScrollTest(); + isScrolling = false; + } + } + super.onDraw(canvas); + } + + /* + * Called once the page is loaded to start scrolling for evaluating tiles + */ + public void startScrollTest(ProfileCallback callback) { + isScrolling = true; + mCallback = callback; + super.tileProfilingStart(); + invalidate(); + } + + /* + * Called once the page has stopped scrolling + */ + public void stopScrollTest() { + float testRatio = super.tileProfilingStop(); + + TileData data[][] = new TileData[super.tileProfilingNumFrames()][]; + for (int frame = 0; frame < data.length; frame++) { + data[frame] = new TileData[ + super.tileProfilingNumTilesInFrame(frame)]; + for (int tile = 0; tile < data[frame].length; tile++) { + int x = super.tileProfilingGetX(frame, tile); + int y = super.tileProfilingGetY(frame, tile); + boolean isReady = super.tileProfilingGetReady(frame, tile); + int level = super.tileProfilingGetLevel(frame, tile); + + data[frame][tile] = new TileData(x, y, isReady, level); + } + } + super.tileProfilingClear(); + + mCallback.profileCallback(data); + } + + @Override + public void loadUrl(String url) { + if (!url.startsWith("http://")) { + url = "http://" + url; + } + super.loadUrl(url); + } + + public void setAutoScrollSpeed(int speedInt) { + mSpeed = speedInt; + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java new file mode 100644 index 0000000..7d4bb9f --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java @@ -0,0 +1,32 @@ +/* + * 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.test.tilebenchmark; + +import java.io.Serializable; + +public class TileData implements Serializable { + public int x, y; + public boolean isReady; + public int level; + + public TileData(int x, int y, boolean isReady, int level) { + this.x = x; + this.y = y; + this.isReady = isReady; + this.level = level; + } +} |